27 #include <Classes.hpp>
28 #include <Controls.hpp>
29 #include <StdCtrls.hpp>
31 #include <Buttons.hpp>
32 #include <ExtCtrls.hpp>
34 #include <Dialogs.hpp>
35 #include <Graphics.hpp>
36 #include <ComCtrls.hpp>
59 #include <Filectrl.hpp>
62 #include <Vcl.HTMLHelpViewer.hpp>
63 #pragma package(smart_init)
64 #pragma link "Vcl.HTMLHelpViewer" //added at v2.0.0 for access to the .chm help file
65 #pragma resource "*.dfm"
84 Screen->Cursor = TCursor(-11);
150 "program operation may be restricted");
153 Application->HelpFile = AnsiString(
CurDir +
"\\Help.chm");
161 int DispW = (Screen->Width - 64) / 16;
162 int DispH = (Screen->Height - 192) / 16;
166 Display =
new TDisplay(
MainScreen,
PerformanceLogBox,
OutputLog1,
OutputLog2,
OutputLog3,
OutputLog4,
OutputLog5,
OutputLog6,
OutputLog7,
OutputLog8,
235 std::ifstream ConfigFile((
CurDir +
"\\Config.txt").c_str());
236 if(ConfigFile.fail())
239 SigImagePanel->Caption =
"Signals will be on the left hand side of the track";
245 "This program is free software released under the terms of the GNU General Public License Version 3, as published by the Free Software Foundation. "
246 "It may be used or redistributed in accordance with that license and is released in the hope that it will be useful, but WITHOUT ANY WARRANTY; "
247 "without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details - "
248 "you should have received a copy along with this program but if not see <http://www.gnu.org/licenses/>.");
252 AnsiString ConfigStr =
"";
260 AnsiString ConfigValue = ConfigStr.SubString(9, ConfigStr.Length() - 8);
261 if(ConfigStr.SubString(1, 8) ==
"Signals=")
263 if(ConfigValue ==
"right")
275 SigImagePanel->Caption =
"Signals will be on the right hand side of the track";
284 SigImagePanel->Caption =
"Signals will be on the left hand side of the track";
291 if(ConfigStr.SubString(1, 8) ==
"BgndCol=")
295 if(ConfigValue ==
"white")
299 else if(ConfigValue ==
"blue")
304 if(ConfigStr.SubString(1, 8) ==
"RLYLocn=")
306 if(DirectoryExists(ConfigValue))
312 else if(ConfigStr.SubString(1, 8) ==
"TTBLocn=")
314 if(DirectoryExists(ConfigValue))
316 TimetableDialog->InitialDir = ConfigStr.SubString(9, ConfigStr.Length() - 8);
317 SaveTTDialog->InitialDir = ConfigStr.SubString(9, ConfigStr.Length() - 8);
320 else if(ConfigStr.SubString(1, 8) ==
"SSNLocn=")
322 if(DirectoryExists(ConfigValue))
328 while(!ConfigFile.eof());
426 SpeedButton96->Glyph->LoadFromResourceName(0,
"ConcourseGlyph");
490 FontButton->Glyph->LoadFromResourceName(0,
"FontGraphic");
491 HomeButton->Glyph->LoadFromResourceName(0,
"Home");
510 SetGapsButton->Glyph->LoadFromResourceName(0,
"ConnectGaps");
521 CallOnImage->Picture->Bitmap->LoadFromResourceName(0,
"CallingOn");
522 CrashImage->Picture->Bitmap->LoadFromResourceName(0,
"CrashWarning");
523 DerailImage->Picture->Bitmap->LoadFromResourceName(0,
"DerailWarning");
524 SignalStopImage->Picture->Bitmap->LoadFromResourceName(0,
"SignalStopWarning");
525 SPADImage->Picture->Bitmap->LoadFromResourceName(0,
"SPADWarning");
526 TrainFailedImage->Picture->Bitmap->LoadFromResourceName(0,
"TrainFailedWarning");
528 DistanceKey->Picture->Bitmap->LoadFromResourceName(0,
"DistanceKey");
529 PrefDirKey->Picture->Bitmap->LoadFromResourceName(0,
"PrefDirKey");
531 TrackLinkedImage->Picture->Bitmap->LoadFromResourceName(0,
"TrackLinkedGraphic");
533 GapsNotSetImage->Picture->Bitmap->LoadFromResourceName(0,
"GapsNotSetGraphic");
534 GapsSetImage->Picture->Bitmap->LoadFromResourceName(0,
"GapsSetGraphic");
545 AnsiString NL =
'\n';
546 const AnsiString TTLabelStr1 =
"Start new train" + NL +
"Start new service from a split" + NL +
"Start new service from another service" + NL +
547 "Start new non-repeating shuttle finish service" + NL +
"Start new shuttle train at a timetabled stop" + NL +
548 "Start new shuttle service from a feeder";
550 const AnsiString TTLabelStr2 =
"Pass" + NL +
"Be joined by another train" + NL +
"Front split" + NL +
"Rear split" + NL +
"Change direction of train";
552 const AnsiString TTLabelStr3 =
"Finish && form a new service" + NL +
"Finish && join another train" + NL +
"Finish && exit railway" + NL +
553 "Finish && repeat shuttle, finally remain here" + NL +
"Finish && repeat shuttle, finally form a finishing service" + NL +
554 "Finish non-repeating shuttle feeder service" + NL +
"Finish && remain here";
556 const AnsiString TTLabelStr4 =
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
557 "HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
" " + NL +
"R";
559 const AnsiString TTLabelStr5 =
"HH:MM ';' Location" + NL +
"HH:MM ';' HH:MM ';' Location";
561 const AnsiString TTLabelStr6 =
"+ rear element ID - space - front element ID [+ optional ';S']" + NL +
"+ ref. of the train that splits" + NL +
562 "+ other service ref." + NL +
"+ shuttle service ref." + NL +
"+ rear element ID - space - front element ID ';' linked shuttle ref." + NL +
563 "+ linked shuttle service ref. ';' feeder service ref." + NL +
"+ location" + NL +
"+ joining train ref." + NL +
"+ new service ref." + NL +
564 "+ new service ref." + NL +
" " + NL +
"+ new service ref." + NL +
"+ ref. of train to join" + NL +
565 "+ list of valid exit element IDs (at least 1) separated by spaces" + NL +
"+ linked shuttle service ref.";
567 const AnsiString TTLabelStr7 =
"Arrival OR departure time (program will determine which from the context) + location." + NL +
568 "Arrival time, departure time (with no events between) + location";
570 const AnsiString TTLabelStr9 =
"Timetable entries" + NL +
"(service references etc.)";
571 const AnsiString TTLabelStr11 =
"Timetable" + NL +
"start time";
573 const AnsiString TTLabelStr12 =
"NB: WITHIN SERVICES commas must" + NL +
"not be used (have special meanings)," + NL +
574 "and semicolons may only be used to" + NL +
"separate service components.";
576 const AnsiString TTLabelStr13 =
"+ linked shuttle service ref. ';' finishing service ref." + NL +
"+ linked shuttle service ref.";
578 const AnsiString TTLabelStr15 =
"Repeat the service + ';' minutes between repeats ';' digit increment ';' number of repeats (last line of service)";
601 if((Screen->Width < 1024) || (Screen->Height < 768))
603 ShowMessage(
"Please note that this program works best with a screen resolution of at least 1024 x 768. Please change if possible");
609 WindowState = wsMaximized;
621 Screen->Cursor = TCursor(-2);
650 char *LocalNumericInformation = setlocale(LC_NUMERIC,
"");
652 if(LocalNumericInformation ==
"")
657 struct lconv *conv = &Locale;
663 catch(
const EFOpenError &e)
667 MessageDlg(e.Message +
" - program must terminate", mtError, But, 0);
668 Application->Terminate();
671 catch(
const Exception &e)
675 AnsiString Message =
"A fatal error occurred during the program setup process, the program must terminate. Message = " + e.Message;
676 MessageDlg(Message, mtError, But, 0);
678 Application->Terminate();
689 AnsiString ColourStr =
"", SignalStr =
"";
690 remove((
CurDir +
"\\Config.txt").c_str());
691 std::ofstream ConfigFile((
CurDir +
"\\Config.txt").c_str());
707 ConfigFile << AnsiString(
"Signals=") << SignalStr <<
'\n';
708 ConfigFile << AnsiString(
"BgndCol=") << ColourStr <<
'\n';
709 ConfigFile << AnsiString(
"RLYLocn=") << AnsiString(
LoadRailwayDialog->InitialDir) <<
'\n';
710 ConfigFile << AnsiString(
"TTBLocn=") << AnsiString(
TimetableDialog->InitialDir) <<
'\n';
711 ConfigFile << AnsiString(
"SSNLocn=") << AnsiString(
LoadSessionDialog->InitialDir) <<
'\n';
734 catch(
const Exception &e)
750 catch(
const Exception &e)
769 Screen->Cursor = TCursor(-2);
779 Screen->Cursor = TCursor(-2);
786 catch(
const Exception &e)
803 catch(
const Exception &e)
816 UnicodeString strVersion = L
"N/A";
818 VersionSize = GetFileVersionInfoSizeW(Application->ExeName.c_str(), &VersionHandle);
821 pBuffer =
new BYTE[VersionSize];
823 if(GetFileVersionInfoW(Application->ExeName.c_str(), VersionHandle, VersionSize, pBuffer))
825 VS_FIXEDFILEINFO *fi;
829 if(VerQueryValueW(pBuffer, L
"\\", (
void**)&fi, &buflen))
832 strVersion.sprintf(L
"%d.%d.%d", HIWORD(fi->dwFileVersionMS), LOWORD(fi->dwFileVersionMS), HIWORD(fi->dwFileVersionLS)
841 return L
" v" + strVersion;
857 catch(
const Exception &e)
876 catch(
const Exception &e)
890 if(((TSpeedButton*)Sender)->Down)
899 Screen->Cursor = TCursor(-11);
900 InfoPanel->Caption =
"SELECTING: Filling area with chosen element";
901 bool FillSelectionFlag =
false;
904 UnicodeString MessageStr =
"Click 'Yes' to fill the area with the chosen element or 'No' to abort.\n"
905 "Existing elements won't be overwritten although track can\n"
906 "have platforms and non-station named location elements added.\n\nThis message will not be shown again.";
907 int button = Application->MessageBox(MessageStr.c_str(), L
"", MB_YESNO);
910 FillSelectionFlag =
true;
915 bool TrackLinkingRequiredFlag =
true;
942 Screen->Cursor = TCursor(-2);
953 catch(
const Exception &e)
987 ShowMessage(
"Incomplete track or other error - see inverted element (may be behind this message)");
998 ShowMessage(
"Unable to set any track links");
1011 ShowMessage(
"Successful Completion");
1027 catch(
const Exception &e)
1048 catch(
const Exception &e)
1067 catch(
const Exception &e)
1086 catch(
const Exception &e)
1105 TFont *TempFont =
new TFont;
1113 TempText.
Font = DisplayFont;
1120 else if(Key ==
'\x1B')
1126 catch(
const Exception &e)
1145 catch(
const Exception &e)
1160 ShowMessage(
"Error, location name being entered without an entry in LNPendingList");
1180 Screen->Cursor = TCursor(-11);
1182 AnsiString ExistingName;
1189 UnicodeString MessageStr = UnicodeString(
"Another location named '") +
LocationNameTextBox->Text +
1190 UnicodeString(
"' already exists. If you continue its name will be erased. Do you wish to continue?");
1191 int button = Application->MessageBox(MessageStr.c_str(), L
"Warning!", MB_YESNO | MB_ICONWARNING);
1195 Screen->Cursor = TCursor(-2);
1206 bool UseExistingPosition =
false;
1213 if(ExistingName !=
"")
1216 UseExistingPosition =
true;
1219 Screen->Cursor = TCursor(-2);
1233 bool UseExistingPosition =
false;
1235 UseExistingPosition =
true;
1238 Screen->Cursor = TCursor(-2);
1250 LocStr = LocStr.Trim();
1259 if((LocStr !=
"") && (LocStr[1] >=
'0') && (LocStr[1] <=
'9'))
1261 Screen->Cursor = TCursor(-2);
1262 ShowMessage(
"Location name can't begin with a number");
1270 if(LocStr.Length() > 50)
1272 Screen->Cursor = TCursor(-2);
1273 ShowMessage(
"Location name too long, 50 characters maximum");
1281 for(
int x = 1; x <= LocStr.Length(); x++)
1283 char Ch = LocStr[x];
1284 if((Ch !=
' ') && (Ch !=
'&') && (Ch !=
'(') && (Ch !=
')') && (Ch !=
':') && (Ch != 39) && (Ch !=
'.') && (Ch !=
'-') && (Ch !=
'+') &&
1285 (Ch !=
'/') && ((Ch <
'0') || (Ch >
'9')) && ((Ch <
'A') || (Ch >
'Z')) && ((Ch <
'a') || (Ch >
'z')))
1287 Screen->Cursor = TCursor(-2);
1289 "Location name contains one or more invalid characters, must be alphanumeric, brackets, space, full stop, colon, inverted comma, '-', '+', '/' or '&&'");
1300 Screen->Cursor = TCursor(-2);
1301 ShowMessage(
"Location name cannot be 'cdt', this name would interfere with the timetable");
1312 bool UseExistingPosition =
false;
1313 if(ExistingName !=
"")
1316 UseExistingPosition =
true;
1319 Screen->Cursor = TCursor(-2);
1328 Screen->Cursor = TCursor(-2);
1331 catch(
const Exception &e)
1352 catch(
const Exception &e)
1365 int Dist = 0, SpeedLimit = 0;
1368 DistanceStr =
"No change";
1371 SpeedStr =
"No change";
1374 if(DistanceStr ==
"No change")
1376 if(SpeedStr ==
"No change")
1386 if(((Dist != -1) && (DistanceStr.Length() > 6)) || ((SpeedLimit != -1) && (SpeedStr.Length() > 6)))
1388 ShowMessage(
"One or more entries too long");
1392 if((DistanceStr ==
"") || (SpeedStr ==
""))
1394 ShowMessage(
"One or more entries blank");
1400 for(
int x = 1; x <= DistanceStr.Length(); x++)
1402 if((DistanceStr[x] <
'0') || (DistanceStr[x] >
'9'))
1404 ShowMessage(
"Track length value must be a positive whole number, or blank for no change");
1412 for(
int x = 1; x <= DistanceStr.Length(); x++)
1414 if((DistanceStr[x] <
'0') || (DistanceStr[x] >
'9'))
1416 ShowMessage(
"Distance must be a positive whole number");
1424 for(
int x = 1; x <= SpeedStr.Length(); x++)
1426 if((SpeedStr[x] <
'0') || (SpeedStr[x] >
'9'))
1428 ShowMessage(
"Speed limit must be a positive whole number, or blank for no change");
1436 for(
int x = 1; x <= SpeedStr.Length(); x++)
1438 if((SpeedStr[x] <
'0') || (SpeedStr[x] >
'9'))
1440 ShowMessage(
"Speed limit must be a positive whole number, or 'Mixed'");
1447 Dist = DistanceStr.ToInt();
1448 if(SpeedLimit != -1)
1449 SpeedLimit = SpeedStr.ToInt();
1457 if(((Dist != -1) && (Dist < 20)) || ((SpeedLimit != -1) && (SpeedLimit < 10)) || ((SpeedLimit != -1) && (SpeedLimit >
TTrain::MaximumSpeedLimit)))
1460 ShowMessage(
"Lengths must be 20m or more, and speeds must be between 10km/h and 400km/h");
1473 bool NamedLocPresent =
false;
1476 for(
int x = LowSelectHLoc; x < HighSelectHLoc; x++)
1478 for(
int y = LowSelectVLoc; y < HighSelectVLoc; y++)
1481 NamedLocPresent =
true;
1485 if(NamedLocPresent && (Dist < 50))
1487 ShowMessage(
"Note: Named location elements are quite short. If they are too short the simulation might depart too far from reality.");
1490 if(NamedLocPresent && (Dist > 200))
1492 ShowMessage(
"Note: Named location elements are quite long. If they are too long the simulation might depart too far from reality.");
1495 for(
int x = LowSelectHLoc; x < HighSelectHLoc; x++)
1497 for(
int y = LowSelectVLoc; y < HighSelectVLoc; y++)
1534 catch(
const Exception &e)
1557 catch(
const Exception &e)
1569 TMsgDlgButtons Buttons;
1570 Buttons << mbYes << mbNo;
1571 if(MessageDlg(
"This will reset the selected elements to default lengths & speed limits. Proceed?", mtWarning, Buttons, 0) == mrNo)
1589 for(
int x = LowSelectHLoc; x < HighSelectHLoc; x++)
1591 for(
int y = LowSelectVLoc; y < HighSelectVLoc; y++)
1645 throw Exception(
"Error, XLinkPos > 1 in SetOneDefaultTrackLength at " + AnsiString(TrackElement.
HLoc) +
" & " +
1646 AnsiString(TrackElement.
VLoc));
1662 catch(
const Exception &e)
1674 TMsgDlgButtons Buttons;
1675 Buttons << mbYes << mbNo;
1676 if(MessageDlg(
"This will reset ALL track elements to default lengths & speed limits. Proceed?", mtWarning, Buttons, 0) == mrNo)
1697 catch(
const Exception &e)
1725 bool GraphicFoundInVector =
false;
1726 for(TTrack::TUserGraphicVector::iterator UGVIt =
Track->
UserGraphicVector.begin(); UGVIt < Track->UserGraphicVector.end(); UGVIt++)
1728 if(UGMIt->first == UGVIt->FileName)
1730 GraphicFoundInVector =
true;
1734 if(!GraphicFoundInVector)
1736 delete UGMIt->second;
1752 catch(
const Exception &e)
1792 catch(
const Exception &e)
1831 catch(
const Exception &e)
1855 catch(
const Exception &e)
1881 catch(
const Exception &e)
1900 catch(
const Exception &e)
1915 ShowMessage(
"No preferred direction selection");
1919 Screen->Cursor = TCursor(-11);
1924 Screen->Cursor = TCursor(-2);
1927 catch(
const Exception &e)
1940 TMsgDlgButtons Buttons;
1941 Buttons << mbYes << mbNo;
1942 if(MessageDlg(
"Do you really want to clear all preferred directions?", mtWarning, Buttons, 0) == mrNo)
1958 catch(
const Exception &e)
1973 Screen->Cursor = TCursor(-11);
1982 Screen->Cursor = TCursor(-2);
1985 catch(
const Exception &e)
2003 catch(
const Exception &e)
2024 catch(
const Exception &e)
2049 catch(
const Exception &e)
2073 InfoPanel->Caption =
"PRE-START: Select AUTOMATIC SIGNAL ROUTE start signal, or left click points to change manually";
2075 InfoPanel->Caption =
"OPERATING: Select AUTOMATIC SIGNAL ROUTE start signal, or left click points to change manually";
2083 catch(
const Exception &e)
2107 InfoPanel->Caption =
"PRE-START: Select PREFERRED ROUTE start signal, or left click points to change manually";
2109 InfoPanel->Caption =
"OPERATING: Select PREFERRED ROUTE start signal, or left click points to change manually";
2117 catch(
const Exception &e)
2147 InfoPanel->Caption =
"PRE-START: Select UNRESTRICTED ROUTE start location, or left click points to change manually";
2149 InfoPanel->Caption =
"OPERATING: Select UNRESTRICTED ROUTE start location, or left click points to change manually";
2157 catch(
const Exception &e)
2172 InfoPanel->Caption =
"ROUTE CANCELLING: Right click on truncate element, first element to cancel (anywhere else to skip)";
2179 catch(
const Exception &e)
2206 catch(
const Exception &e)
2221 UnicodeString MessageStr =
"Please note that the session will be lost if it hasn't been saved. Do you still wish to exit?";
2224 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
2262 catch(
const Exception &e)
2304 catch(
const Exception &e)
2316 Screen->Cursor = TCursor(-11);
2317 std::ifstream VecFile(LoadFileName.c_str());
2318 if(!(VecFile.fail()))
2323 bool GraphicsFollow =
false;
2342 TFont *TempFont =
new TFont;
2343 TempFont->Style.Clear();
2344 TempFont->Name =
"MS Sans Serif";
2345 TempFont->Size = 10;
2347 TempFont->Charset = (TFontCharset)(0);
2356 if((LeftExcess > 0) && (RightExcess > 0))
2358 else if((LeftExcess > 0) && (RightExcess <= 0))
2361 else if((LeftExcess <= 0) && (RightExcess > 0))
2369 if((TopExcess > 0) && (BotExcess > 0))
2371 else if((TopExcess > 0) && (BotExcess <= 0))
2374 else if((TopExcess <= 0) && (BotExcess > 0))
2386 if((LastChar ==
'y') || (LastChar ==
'Y'))
2390 ShowMessage(
"Railway not ready for operation so unable to load as a .rly file. Loading as a new railway under development");
2397 Screen->Cursor = TCursor(-2);
2430 ShowMessage(
"File open failed prior to load");
2431 Screen->Cursor = TCursor(-2);
2434 ShowMessage(
"File integrity check failed - unable to load");
2449 Screen->Cursor = TCursor(-11);
2451 if(!(VecFile.fail()))
2478 ShowMessage(
"File open failed prior to save");
2479 Screen->Cursor = TCursor(-2);
2484 catch(
const Exception &e)
2500 catch(
const Exception &e)
2516 ShowMessage(
"Failed to find folder " +
IMAGE_DIR_NAME +
" in the folder where 'railway.exe' resides. Image can't be saved");
2520 Screen->Cursor = TCursor(-11);
2523 AnsiString ImageFileName = TDateTime::CurrentDateTime().FormatString(
"dd-mm-yyyy hh.nn.ss");
2527 AnsiString ShortName =
"";
2528 for(
int x = ImageFileName.Length(); x > 0; x--)
2530 if(ImageFileName[x] ==
'\\')
2532 ShortName = ImageFileName.SubString(x + 1, ImageFileName.Length() - x - 4);
2536 ShowMessage(
"A bitmap file named " + ShortName +
" will be created in the Images folder");
2537 Graphics::TBitmap *RailwayImage =
new Graphics::TBitmap;
2538 RailwayImage->PixelFormat = pf8bit;
2544 RailwayImage->Width = HPosMax - HPosMin;
2545 RailwayImage->Height = VPosMax - VPosMin;
2553 int NewWidth = (TextPtr->HPos - HPosMin) + (abs(TextPtr->Font->Height) * TextPtr->TextString.Length() * 0.7);
2554 int NewHeight = (TextPtr->VPos - VPosMin) + (abs(TextPtr->Font->Height) * 1.5);
2555 if(NewWidth > RailwayImage->Width)
2557 RailwayImage->Width = NewWidth;
2559 if(NewHeight > RailwayImage->Height)
2561 RailwayImage->Height = NewHeight;
2566 RailwayImage->Canvas->Brush->Color =
clB5G5R5;
2567 TRect Rect(0, 0, RailwayImage->Width, RailwayImage->Height);
2568 RailwayImage->Canvas->FillRect(Rect);
2576 RailwayImage->SaveToFile(ImageFileName);
2577 delete RailwayImage;
2580 Screen->Cursor = TCursor(-2);
2583 catch(
const Exception &e)
2585 if(e.Message.Pos(
"torage") > 0)
2587 Screen->Cursor = TCursor(-2);
2588 UnicodeString MessageStr =
"Insufficient memory available to store this image";
2589 Application->MessageBox(MessageStr.c_str(), L
"", MB_OK | MB_ICONWARNING);
2608 ShowMessage(
"Failed to find folder " +
IMAGE_DIR_NAME +
" in the folder where 'railway.exe' resides. Image can't be saved");
2612 Screen->Cursor = TCursor(-11);
2615 AnsiString ImageFileName = TDateTime::CurrentDateTime().FormatString(
"dd-mm-yyyy hh.nn.ss");
2619 AnsiString ShortName =
"";
2620 for(
int x = ImageFileName.Length(); x > 0; x--)
2622 if(ImageFileName[x] ==
'\\')
2624 ShortName = ImageFileName.SubString(x + 1, ImageFileName.Length() - x - 4);
2628 ShowMessage(
"A bitmap file named " + ShortName +
" will be created in the Images folder");
2629 Graphics::TBitmap *RailwayImage =
new Graphics::TBitmap;
2630 RailwayImage->PixelFormat = pf8bit;
2635 RailwayImage->Width = HPosMax - HPosMin;
2636 RailwayImage->Height = VPosMax - VPosMin;
2644 int NewWidth = (TextPtr->HPos - HPosMin) + (abs(TextPtr->Font->Height) * TextPtr->TextString.Length() * 0.7);
2645 int NewHeight = (TextPtr->VPos - VPosMin) + (abs(TextPtr->Font->Height) * 1.5);
2646 if(NewWidth > RailwayImage->Width)
2648 RailwayImage->Width = NewWidth;
2650 if(NewHeight > RailwayImage->Height)
2652 RailwayImage->Height = NewHeight;
2657 RailwayImage->Canvas->Brush->Color =
clB5G5R5;
2658 TRect Rect(0, 0, RailwayImage->Width, RailwayImage->Height);
2659 RailwayImage->Canvas->FillRect(Rect);
2662 for(
int x = 0; x < ((RailwayImage->Width) / 16); x++)
2664 for(
int y = 0; y < ((RailwayImage->Height) / 16); y++)
2674 RailwayImage->SaveToFile(ImageFileName);
2675 delete RailwayImage;
2678 Screen->Cursor = TCursor(-2);
2681 catch(
const Exception &e)
2683 if(e.Message.Pos(
"torage") > 0)
2685 Screen->Cursor = TCursor(-2);
2686 UnicodeString MessageStr =
"Insufficient memory available to store this image";
2687 Application->MessageBox(MessageStr.c_str(), L
"", MB_OK | MB_ICONWARNING);
2705 ShowMessage(
"Failed to find folder " +
IMAGE_DIR_NAME +
" in the folder where 'railway.exe' resides. Image can't be saved");
2709 Screen->Cursor = TCursor(-11);
2712 AnsiString ImageFileName = TDateTime::CurrentDateTime().FormatString(
"dd-mm-yyyy hh.nn.ss");
2716 AnsiString ShortName =
"";
2717 for(
int x = ImageFileName.Length(); x > 0; x--)
2719 if(ImageFileName[x] ==
'\\')
2721 ShortName = ImageFileName.SubString(x + 1, ImageFileName.Length() - x - 4);
2725 ShowMessage(
"A bitmap file named " + ShortName +
" will be created in the Images folder");
2726 Graphics::TBitmap *RailwayImage =
new Graphics::TBitmap;
2727 RailwayImage->PixelFormat = pf8bit;
2732 RailwayImage->Width = HPosMax - HPosMin;
2733 RailwayImage->Height = VPosMax - VPosMin;
2741 int NewWidth = (TextPtr->HPos - HPosMin) + (abs(TextPtr->Font->Height) * TextPtr->TextString.Length() * 0.7);
2742 int NewHeight = (TextPtr->VPos - VPosMin) + (abs(TextPtr->Font->Height) * 1.5);
2743 if(NewWidth > RailwayImage->Width)
2745 RailwayImage->Width = NewWidth;
2747 if(NewHeight > RailwayImage->Height)
2749 RailwayImage->Height = NewHeight;
2754 RailwayImage->Canvas->Brush->Color =
clB5G5R5;
2755 TRect Rect(0, 0, RailwayImage->Width, RailwayImage->Height);
2756 RailwayImage->Canvas->FillRect(Rect);
2764 RailwayImage->SaveToFile(ImageFileName);
2765 delete RailwayImage;
2768 Screen->Cursor = TCursor(-2);
2771 catch(
const Exception &e)
2773 if(e.Message.Pos(
"torage") > 0)
2775 Screen->Cursor = TCursor(-2);
2776 UnicodeString MessageStr =
"Insufficient memory available to store this image";
2777 Application->MessageBox(MessageStr.c_str(), L
"", MB_OK | MB_ICONWARNING);
2795 ShowMessage(
"Failed to find folder " +
IMAGE_DIR_NAME +
" in the folder where 'railway.exe' resides. Image can't be saved");
2799 Screen->Cursor = TCursor(-11);
2804 TimetableTimeStr = TimetableTimeStr.SubString(1, 2) +
'.' + TimetableTimeStr.SubString(4, 2) +
'.' + TimetableTimeStr.SubString(7, 2);
2805 AnsiString ImageFileName = TDateTime::CurrentDateTime().FormatString(
"dd-mm-yyyy hh.nn.ss");
2810 AnsiString ShortName =
"";
2811 for(
int x = ImageFileName.Length(); x > 0; x--)
2813 if(ImageFileName[x] ==
'\\')
2815 ShortName = ImageFileName.SubString(x + 1, ImageFileName.Length() - x - 4);
2819 ShowMessage(
"A bitmap file named " + ShortName +
" will be created in the Images folder");
2820 Graphics::TBitmap *RailwayImage =
new Graphics::TBitmap;
2821 RailwayImage->PixelFormat = pf8bit;
2826 RailwayImage->Width = HPosMax - HPosMin;
2827 RailwayImage->Height = VPosMax - VPosMin;
2835 int NewWidth = (TextPtr->HPos - HPosMin) + (abs(TextPtr->Font->Height) * TextPtr->TextString.Length() * 0.7);
2836 int NewHeight = (TextPtr->VPos - VPosMin) + (abs(TextPtr->Font->Height) * 1.5);
2837 if(NewWidth > RailwayImage->Width)
2839 RailwayImage->Width = NewWidth;
2841 if(NewHeight > RailwayImage->Height)
2843 RailwayImage->Height = NewHeight;
2848 RailwayImage->Canvas->Brush->Color =
clB5G5R5;
2849 TRect Rect(0, 0, RailwayImage->Width, RailwayImage->Height);
2850 RailwayImage->Canvas->FillRect(Rect);
2865 bool BreakFlag =
false;
2891 RailwayImage->SaveToFile(ImageFileName);
2892 delete RailwayImage;
2895 Screen->Cursor = TCursor(-2);
2898 catch(
const Exception &e)
2900 if(e.Message.Pos(
"torage") > 0)
2902 Screen->Cursor = TCursor(-2);
2903 UnicodeString MessageStr =
"Insufficient memory available to store this image";
2904 Application->MessageBox(MessageStr.c_str(), L
"", MB_OK | MB_ICONWARNING);
2932 Screen->Cursor = TCursor(-11);
2934 if(!(VecFile.fail()))
2961 ShowMessage(
"Railway failed to save - can't open file");
2962 Screen->Cursor = TCursor(-2);
2966 catch(
const Exception &e)
2980 catch(
const Exception &e)
3000 catch(
const Exception &e)
3015 ShowMessage(
"Failed to find folder " +
FORMATTEDTT_DIR_NAME +
" in the folder where 'railway.exe' resides. Timetable can't be exported");
3023 Screen->Cursor = TCursor(-2);
3026 catch(
const Exception &e)
3086 AZOrderButton->Hint = AnsiString(
"Arrange services in alphabetical order Toggle with Shift+ Z");
3103 ActiveTrackElementNameMapEntry.first =
Track->
TrackVector.at(x).ActiveTrackElementName;
3104 ActiveTrackElementNameMapEntry.second = 0;
3154 catch(
const Exception &e)
3203 if(TTBLFile.is_open())
3207 while(!TTBLFile.eof())
3210 if((c < 32) && (c != 13) && (c != 10) && (c !=
'\0'))
3212 ShowMessage(
"Timetable file is empty or contains non-ascii characters, codes must be between 20 and 127, or CR or LF");
3222 ShowMessage(
"Failed to open timetable file, make sure it's not open in another application");
3229 if(TTBLFile.is_open())
3238 AZOrderButton->Hint = AnsiString(
"Arrange services in alphabetical order Toggle with Shift+ Z");
3251 char *TimetableEntryString =
new char[10000];
3254 TTBLFile.getline(TimetableEntryString, 10000,
'\0');
3255 if(TTBLFile.eof() && (TimetableEntryString[0] ==
'\0'))
3260 AnsiString OneLine(TimetableEntryString);
3264 delete TimetableEntryString;
3269 ShowMessage(
"Failed to open timetable file, make sure it's not open in another application");
3305 ActiveTrackElementNameMapEntry.first =
Track->
TrackVector.at(x).ActiveTrackElementName;
3306 ActiveTrackElementNameMapEntry.second = 0;
3331 catch(
const Exception &e)
3350 InfoPanel->Caption =
"Timetable mode: editor hidden";
3357 ShowHideTTButton->Hint =
"Hide the timetable editor to see the railway Shift H";
3362 catch(
const Exception &e)
3401 catch(
const Exception &e)
3440 catch(
const Exception &e)
3460 catch(
const Exception &e)
3473 bool ValidFlag =
true;
3492 TDateTime DummyTime;
3510 ShowMessage(
"One or more times excessive, not permitted to exceed 95 hours");
3514 AnsiString MinsStr = AnsiString(Mins), HrsStr = AnsiString(Hrs);
3516 MinsStr =
"0" + MinsStr;
3518 HrsStr =
"0" + HrsStr;
3521 NewString += HrsStr +
':' + MinsStr;
3538 catch(
const Exception &e)
3551 bool ValidFlag =
true;
3570 TDateTime DummyTime;
3588 ShowMessage(
"One or more times are now before 00:00, this is not permitted");
3592 AnsiString MinsStr = AnsiString(Mins), HrsStr = AnsiString(Hrs);
3594 MinsStr =
"0" + MinsStr;
3596 HrsStr =
"0" + HrsStr;
3599 NewString += HrsStr +
':' + MinsStr;
3615 catch(
const Exception &e)
3653 catch(
const Exception &e)
3699 if(OldVectorPos == 0)
3727 catch(
const Exception &e)
3786 catch(
const Exception &e)
3804 UnicodeString MessageStr =
"Are you sure this entry should be deleted?";
3805 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
3837 if(OldVectorPos == 0)
3865 catch(
const Exception &e)
3886 AnsiString TempStr =
"";
3887 bool ActiveLine =
false;
3912 while(TempStr[TempStr.Length()] ==
',')
3914 TempStr = TempStr.SubString(1, TempStr.Length() - 1);
3943 (*TTCurrentEntryPtr) = TempStr;
4013 catch(
const Exception &e)
4028 ShowMessage(
"Timetable is empty, can't save an empty timetable");
4032 std::ofstream TTBLFile;
4067 if(TTBLFile.is_open())
4071 TTBLFile << (*TEVPtr).c_str() <<
'\0';
4078 ShowMessage(
CreateEditTTFileName +
" failed to open, ensure not already open in another application");
4084 catch(
const Exception &e)
4099 ShowMessage(
"Timetable is empty, can't save an empty timetable");
4103 std::ofstream TTBLFile;
4112 for(
int x =
SaveTTDialog->FileName.Length(); x > 0; x--)
4130 if(TTBLFile.is_open())
4134 TTBLFile << (*TEVPtr).c_str() <<
'\0';
4141 ShowMessage(
CreateEditTTFileName +
" failed to open, ensure not already open in another application");
4147 catch(
const Exception &e)
4161 bool EndOfFile =
false;
4162 bool FinalCallFalse =
false;
4163 bool GiveMessagesTrue =
true;
4164 bool CheckLocationsExistInRailway =
false;
4166 CheckLocationsExistInRailway =
true;
4172 "The basic syntax seems OK but this check is very limited. Other aspects can only be checked by validating the whole timetable with the appropriate railway (.rly) loaded");
4178 catch(
const Exception &e)
4206 bool CheckLocationsExistInRailwayTrue =
true;
4209 Screen->Cursor = TCursor(-11);
4211 if(TTBLFile.is_open())
4215 ShowMessage(
"Timetable integrity OK");
4222 ShowMessage(
"Failed to open timetable file, make sure it's not open in another application");
4224 Screen->Cursor = TCursor(-2);
4234 catch(
const Exception &e)
4258 AnsiString TempStr = *
TEVPtr;
4296 catch(
const Exception &e)
4320 AnsiString TempStr = *
TEVPtr;
4358 catch(
const Exception &e)
4395 catch(
const Exception &e)
4410 UnicodeString MessageStr =
"All changes to the timetable will be lost - proceed?";
4411 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
4422 if(TTBLFile.is_open())
4439 char *TimetableEntryString =
new char[10000];
4442 TTBLFile.getline(TimetableEntryString, 10000,
'\0');
4443 if(TTBLFile.eof() && (TimetableEntryString[0] ==
'\0'))
4448 AnsiString OneLine(TimetableEntryString);
4452 delete TimetableEntryString;
4457 ShowMessage(
"Failed to open timetable file, make sure it's not open in another application");
4478 catch(
const Exception &e)
4493 ShowMessage(
"Failed to find folder " +
FORMATTEDTT_DIR_NAME +
" in the folder where 'railway.exe' resides. Timetable can't be exported");
4512 Screen->Cursor = TCursor(-2);
4517 catch(
const Exception &e)
4550 catch(
const Exception &e)
4565 UnicodeString MessageStr =
"The timetable has changed.\n\nAre you sure you want to exit without saving it?";
4566 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
4582 catch(
const Exception &e)
4610 catch(
const Exception &e)
4635 catch(
const Exception &e)
4653 catch(
const Exception &e)
4676 catch(
const Exception &e)
4685 TShiftState Shift,
int X,
int Y)
4729 catch(
const Exception &e)
4758 if((TopPos + (Y / 13)) >=
OAListBox->Items->Count)
4766 std::advance(OACurrentEntryPtr, ((Y / 13) + TopPos));
4770 int TrackVectorPosition;
4771 int TrainIDorTVPos = OACurrentEntryPtr->second.second;
4772 if(TrainIDorTVPos >= 0)
4788 TrackVectorPosition = -(TrainIDorTVPos + 1);
4803 TPoint MainScreenPoint(ScreenPosH + 8, ScreenPosV + 8);
4804 TPoint CursPos =
MainScreen->ClientToScreen(MainScreenPoint);
4805 Mouse->CursorPos = CursPos;
4808 catch(
const Exception &e)
4820 PreStartTime, ActiveSegment, PostEnd} Segment;
4833 Segment = PreStartTime;
4836 if(Segment == PreStartTime)
4843 Segment = ActiveSegment;
4854 AnsiString CurrentStr = *
TEVPtr;
4855 if(CurrentStr !=
"")
4857 CurrentStr = CurrentStr.SubString(1, 10);
4858 for(
int x = 1; x < CurrentStr.Length(); x++)
4860 if((CurrentStr[x] < 32) || (CurrentStr[1] > 126))
4862 CurrentStr = CurrentStr.SubString(1, (x - 1));
4871 if(Segment == ActiveSegment)
4886 AnsiString Entry = *
TEVPtr;
4891 int SCPos = Entry.Pos(
';');
4892 int CPos = Entry.Pos(
',');
4899 if((CPos == 0) && (SCPos == 0))
4901 Entry = Entry.SubString(1, 12);
4903 else if((CPos > 0) && (SCPos > 0) && (CPos < SCPos))
4905 Entry = Entry.SubString(1, CPos - 1);
4907 else if((CPos > 0) && (SCPos > 0) && (CPos > SCPos))
4909 Entry = Entry.SubString(1, SCPos - 1);
4911 else if((CPos > 0) && (SCPos == 0))
4913 Entry = Entry.SubString(1, CPos - 1);
4917 Entry = Entry.SubString(1, SCPos - 1);
4930 if(Segment == PostEnd)
4938 AnsiString CurrentStr = *
TEVPtr;
4939 if(CurrentStr !=
"")
4941 CurrentStr = CurrentStr.SubString(1, 10);
4942 for(
int x = 1; x < CurrentStr.Length(); x++)
4944 if((CurrentStr[x] < 32) || (CurrentStr[1] > 126))
4946 CurrentStr = CurrentStr.SubString(1, (x - 1));
4977 UnicodeString MessageStr =
4978 "If you wish to preserve the original order don't make any changes whilst in alphabetical order.\n\nIn that case use alphabetical order to find the service required, click it to display it, then revert to the original order where the same service will be displayed and can be changed.";
4979 Application->MessageBox(MessageStr.c_str(), L
"Please Note:", MB_OK | MB_ICONWARNING);
4992 std::sort(SortStart, SortEnd);
4994 bool CurrentEntryChanged =
false;
5000 CurrentEntryChanged =
true;
5003 if(!CurrentEntryChanged)
5008 AZOrderButton->Hint = AnsiString(
"Arrange services in original order Toggle with Shift+ Z");
5014 UnicodeString MessageStr =
5015 "Reverting to the original order will discard any changes made whilst in alphabetical order.\n\nTo preserve the changes click 'No', then save the timetable or use 'save as' if you wish to keep the original timetable.\n\nDo you wish to proceed?";
5016 int button = Application->MessageBox(MessageStr.c_str(), L
"Warning!", MB_YESNO | MB_ICONWARNING);
5030 bool CurrentEntryChanged =
false;
5036 CurrentEntryChanged =
true;
5039 if(!CurrentEntryChanged)
5044 AZOrderButton->Hint = AnsiString(
"Arrange services in alphabetical order Toggle with Shift+ Z");
5053 catch(
const Exception &e)
5064 AnsiString OutStr =
"";
5067 while(x < ConvStr.Length())
5069 if((ConvStr[x] ==
'\r') && (ConvStr[x + 1] ==
'\n'))
5077 OutStr += ConvStr[x];
5081 if(x == ConvStr.Length())
5082 OutStr += ConvStr[x];
5087 while(OutStr[OutStr.Length()] ==
',')
5089 OutStr = OutStr.SubString(1, OutStr.Length() - 1);
5159 InfoPanel->Caption =
"Select option or change entry";
5173 bool ValidFlag =
true;
5174 for(
int x = 1; x <= AnsiAddSubText.Length(); x++)
5176 if((AnsiAddSubText[x] >
'9') || (AnsiAddSubText[x] <
'0'))
5184 if(AnsiAddSubText.ToInt() != 0)
5256 bool ServiceEntry =
true;
5261 bool ServiceEntry =
false;
5273 InfoPanel->Caption =
"Add or change entry then save it, or cancel";
5283 AnsiString((
short)ServiceEntry));
5290 int CommaPos = Data.Pos(
',');
5291 if((CommaPos == 0) && (Data !=
""))
5293 CommaPos = Data.Length() + 1;
5296 if(Data.Length() <= CommaPos)
5298 Data = Data.SubString(CommaPos + 1, Data.Length() - CommaPos);
5335 if(CurrentStr !=
"")
5337 for(
int x = 1; x < CurrentStr.Length(); x++)
5339 if((CurrentStr[x] < 32) || (CurrentStr[1] > 126))
5341 CurrentStr = CurrentStr.SubString(1, (x - 1));
5366 TDateTime DummyTime;
5367 bool TimesPresent =
false;
5375 TimesPresent =
true;
5382 return TimesPresent;
5396 UnicodeString MessageStr =
5397 "Note that leaving the track unlinked will cause preferred directions to be lost on reloading. Prevent by linking the track then resaving. Do you still wish to exit?";
5398 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
5407 UnicodeString MessageStr =
"The railway has changed, exit without saving?";
5408 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
5420 Application->Terminate();
5422 catch(
const Exception &e)
5445 catch(
const Exception &e)
5468 catch(
const Exception &e)
5491 catch(
const Exception &e)
5550 catch(
const Exception &e)
5568 catch(
const Exception &e)
5587 catch(
const Exception &e)
5622 catch(
const Exception &e)
5633 TrainController->
LogEvent(
"MainScreenMouseDown2," + AnsiString(Button) +
"," + AnsiString(X) +
"," + AnsiString(Y));
5635 "," + AnsiString(Y));
5646 int NoOffsetX, NoOffsetY;
5648 if(Button == mbRight)
5652 AnsiString Text =
"";
5659 Screen->Cursor = TCursor(-22);
5710 bool TrackEraseSuccessfulFlag;
5711 int ErasedTrackVectorPosition;
5712 Screen->Cursor = TCursor(-11);
5714 if(TrackEraseSuccessfulFlag)
5716 if(ErasedTrackVectorPosition > -1)
5747 Screen->Cursor = TCursor(-2);
5755 bool LeadingPointsAtLastElement =
false;
5770 if(!LeadingPointsAtLastElement)
5775 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Continue or set values (overall length), or right click to cancel/truncate";
5790 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Can't end on leading points, continue or truncate";
5867 if((TrainID01 > -1) && (TrainID23 > -1))
5917 AnsiString LocName =
"";
5922 if((LocName ==
"") && (Train.
MidElement > -1))
6036 Screen->Cursor = TCursor(-11);
6047 Screen->Cursor = TCursor(-2);
6114 Screen->Cursor = TCursor(-11);
6116 bool TrackLinkingRequiredFlag;
6118 TSpeedButton *TempSpeedButton = 0;
6126 bool InternalChecks =
true;
6132 if(TrackLinkingRequiredFlag)
6161 Screen->Cursor = TCursor(-2);
6175 NewGI.
Width = UGMIt->second->Width;
6176 NewGI.
Height = UGMIt->second->Height;
6201 AnsiString NameString;
6211 unsigned int ValidPosition;
6222 ValidElement = InactiveTrackElement1;
6223 ValidPosition = InactivePair.first;
6228 ValidElement = InactiveTrackElement2;
6229 ValidPosition = InactivePair.second;
6240 InfoPanel->Caption =
"NAMING LOCATIONS: Enter name, 'Carriage Return' to accept, 'Escape' to quit";
6271 bool FinishElement =
false, LeadingPointsAtLastElement =
false;
6272 Screen->Cursor = TCursor(-11);
6286 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Set values (overall length), or right click to cancel/truncate";
6296 Screen->Cursor = TCursor(-2);
6302 if(!LeadingPointsAtLastElement)
6307 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Continue or set values (overall length), or right click to cancel/truncate";
6324 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Can't end on leading points, need to continue or truncate";
6339 Screen->Cursor = TCursor(-2);
6344 Screen->Cursor = TCursor(-2);
6361 InfoPanel->Caption =
"CONNECTING GAPS: Connecting element selected";
6373 ShowMessage(
"All gaps set");
6401 int TrueX = 0, TrueY = 0;
6402 AnsiString ExistingText =
"";
6404 TFont *ExistingTextFont =
new TFont;
6405 int ExistingTextHPos = 0, ExistingTextVPos = 0;
6411 if((TrueX >= TextPtr->HPos) && (TrueX < (TextPtr->HPos + abs(TextPtr->Font->Height))) && (TrueY >= TextPtr->VPos) && (TrueY <
6412 (TextPtr->VPos + abs(TextPtr->Font->Height))))
6414 ExistingText = TextPtr->TextString;
6415 ExistingTextFont->Assign(TextPtr->Font);
6416 ExistingTextHPos = TextPtr->HPos;
6417 ExistingTextVPos = TextPtr->VPos;
6429 TextBox->Font->Assign(ExistingTextFont);
6431 Text_X = ExistingTextHPos;
6432 Text_Y = ExistingTextVPos;
6447 TextBox->Text =
"New Text: CR=end, ESC=quit";
6450 delete ExistingTextFont;
6542 Screen->Cursor = TCursor(-11);
6551 ShowMessage(
"Preferred direction added");
6555 Screen->Cursor = TCursor(-2);
6574 Screen->Cursor = TCursor(-2);
6578 Screen->Cursor = TCursor(-2);
6675 AnsiString(PDE.
VLoc));
6688 bool PointsChanged =
false;
6689 IDInt ReqPosRouteID(-1);
6691 bool CallonTrue =
true;
6692 bool ConsecSignalsRouteFalse =
false;
6701 CallonTrue, ReqPosRouteID, PointsChanged))
6743 float TempSpeedVal = 1;
6811 int DivergingPosition = TrackElement.
Conn[3];
6813 DivergingPosition)))
6841 bool TrainPresent =
false;
6845 int BDVectorPos = -1;
6853 TDateTime TempExcessLCDownTime;
6862 if(TempExcessLCDownTime > TDateTime(0))
6891 AnsiString Message = AnsiString(
"This will open the level crossing manually (it will show in green).\n\nA manually opened"
6892 " level crossing must be manually closed, and as soon as possible to avoid time penalties.\n\n"
6893 "This message will not be shown again.");
6932 InfoPanel->Caption =
"PRE-START: Select next route location";
6934 InfoPanel->Caption =
"OPERATING: Select next route location";
6946 bool CallonFalse =
false;
6953 InfoPanel->Caption =
"PRE-START: Select next route location";
6955 InfoPanel->Caption =
"OPERATING: Select next route location";
6973 Screen->Cursor = TCursor(-11);
6975 bool PointsChanged =
false;
6985 float TempSpeedVal = 1;
6990 else if(PointsChanged)
7001 Screen->Cursor = TCursor(-2);
7009 bool CallonFalse =
false;
7015 float TempSpeedVal = 1;
7020 else if(PointsChanged)
7034 Screen->Cursor = TCursor(-2);
7043 catch(
const Exception &e)
7057 TrainController->
LogEvent(
"MainScreenMouseDown3," + AnsiString(Button) +
"," + AnsiString(X) +
"," + AnsiString(Y));
7059 "," + AnsiString(Y));
7060 if(Button != mbLeft)
7066 Screen->Cursor = TCursor(-22);
7072 int HRounding, VRounding;
7123 else if(TempLevel2OperMode ==
Operating)
7126 OperateButton->Glyph->LoadFromResourceName(0,
"PauseGraphic");
7130 else if(TempLevel2OperMode ==
Paused)
7133 OperateButton->Glyph->LoadFromResourceName(0,
"RunGraphic");
7139 else if(TempLevel2OperMode ==
PreStart)
7142 OperateButton->Glyph->LoadFromResourceName(0,
"RunGraphic");
7153 catch(
const Exception &e)
7243 if(CurrentHLoc >= StartHLoc)
7247 if(CurrentVLoc >= StartVLoc)
7259 TRect TempRect(StartHLoc, StartVLoc, CurrentHLoc, CurrentVLoc);
7273 if(CurrentHLoc >= StartHLoc)
7277 if(CurrentVLoc >= StartVLoc)
7289 TRect TempRect(StartHLoc, StartVLoc, CurrentHLoc, CurrentVLoc);
7348 catch(
const Exception &e)
7384 TrainController->
LogEvent(
"MainScreenMouseUp," + AnsiString(Button) +
"," + AnsiString(X) +
"," + AnsiString(Y));
7387 Screen->Cursor = TCursor(-2);
7391 Screen->Cursor = TCursor(-11);
7396 if(EndHLoc >= StartHLoc)
7400 if(EndVLoc >= StartVLoc)
7404 if(StartHLoc >= EndHLoc)
7414 if(StartVLoc >= EndVLoc)
7440 Screen->Cursor = TCursor(-2);
7506 if(IATVecPair.second != IATVecPair.first)
7524 if((TextPtr->HPos >= LowSelectHPos) && (TextPtr->HPos < HighSelectHPos) && (TextPtr->VPos >= LowSelectVPos) && (TextPtr->VPos <
7532 bool SelectVectorNamedElement =
false;
7533 AnsiString SelectTextString;
7538 SelectVectorNamedElement =
true;
7542 if(SelectVectorNamedElement)
7544 SelectTextString =
"##**" + TextPtr->TextString;
7548 SelectTextString = TextPtr->TextString;
7550 TTextItem TextItem(TextPtr->HPos, TextPtr->VPos, SelectTextString, TextPtr->Font);
7559 for(TTrack::TUserGraphicVector::iterator UserGraphicPtr =
Track->
UserGraphicVector.begin(); UserGraphicPtr < Track->UserGraphicVector.end();
7562 if((UserGraphicPtr->HPos >= LowSelectHPos) && ((UserGraphicPtr->HPos + UserGraphicPtr->Width) < HighSelectHPos) &&
7563 (UserGraphicPtr->VPos >= LowSelectVPos) && ((UserGraphicPtr->VPos + UserGraphicPtr->Height) < HighSelectVPos))
7576 Screen->Cursor = TCursor(-2);
7582 Screen->Cursor = TCursor(-11);
7588 if(EndHLoc >= StartHLoc)
7592 if(EndVLoc >= StartVLoc)
7596 if(StartHLoc >= EndHLoc)
7606 if(StartVLoc >= EndVLoc)
7631 Screen->Cursor = TCursor(-2);
7660 Screen->Cursor = TCursor(-2);
7686 catch(
const Exception &e)
7719 throw Exception(
"Warning - Utilities->CallLog contains more than 50 items");
7746 catch(
const Exception &e)
7826 if(
WholeRailwayMoving && (GetAsyncKeyState(VK_LBUTTON) >= 0) && (GetAsyncKeyState(VK_RBUTTON) >= 0))
7829 Screen->Cursor = TCursor(-2);
7856 bool TrainPresent =
false;
7872 TDateTime TempExcessLCDownTime;
7881 if(TempExcessLCDownTime > TDateTime(0))
7910 bool ElementRemovedFlag =
false;
7921 ElementRemovedFlag =
true;
7936 bool WH1 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog1->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog1->Width +
OutputLog1->Left))
7939 bool WH2 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog2->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog2->Width +
OutputLog2->Left))
7942 bool WH3 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog3->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog3->Width +
OutputLog3->Left))
7945 bool WH4 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog4->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog4->Width +
OutputLog4->Left))
7948 bool WH5 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog5->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog5->Width +
OutputLog5->Left))
7951 bool WH6 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog6->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog6->Width +
OutputLog6->Left))
7954 bool WH7 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog7->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog7->Width +
OutputLog7->Left))
7957 bool WH8 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog8->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog8->Width +
OutputLog8->Left))
7960 bool WH9 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog9->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog9->Width +
OutputLog9->Left))
7963 bool WH10 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog10->Left) &&
7967 if(WH1 || WH2 || WH3 || WH4 || WH5 || WH6 || WH7 || WH8 || WH9 || WH10)
7988 AnsiString Type[15] =
7989 {
"Simple",
"Crossover",
"Points",
"Buffers",
"Bridge",
"SignalPost",
"Continuation",
"Platform",
"GapJump",
"FootCrossing",
"Unused",
"Concourse",
7990 "Parapet",
"NamedNonStationLocation",
"Erase"};
7992 int ScreenX = Mouse->CursorPos.x -
MainScreen->ClientOrigin.x;
7993 int ScreenY = Mouse->CursorPos.y -
MainScreen->ClientOrigin.y;
7995 AnsiString MouseStr =
"Posx: " + AnsiString(ScreenX) +
"; Posy: " + AnsiString(ScreenY);
8000 DevelopmentPanel->Caption = MouseStr +
"; TVPos: " + AnsiString(Position) +
"; H: " + AnsiString(HLoc) +
"; V: " + AnsiString(VLoc) +
8001 "; SpTg: " + AnsiString(TrackElement.
SpeedTag) +
"; Type: " + Type[TrackElement.
TrackType] +
"; Att: " + AnsiString(TrackElement.
Attribute)
8019 if((GetKeyState(VK_LBUTTON) >= 0) && (GetKeyState(VK_RBUTTON) >= 0) && (
TTCurrentEntryPtr > 0))
8150 Screen->Cursor = TCursor(-11);
8306 int RouteStartVecPos;
8316 if(FoundFlag && (RouteStartVecPos > -1))
8332 catch(
const Exception &e)
8350 InfoPanel->Caption =
"CALLING ON: Select signal for call on";
8364 catch(
const Exception &e)
8378 Screen->Cursor = TCursor(-11);
8420 Screen->Cursor = TCursor(-2);
8423 catch(
const Exception &e)
8437 Screen->Cursor = TCursor(-11);
8479 Screen->Cursor = TCursor(-2);
8482 catch(
const Exception &e)
8496 Screen->Cursor = TCursor(-11);
8539 Screen->Cursor = TCursor(-2);
8542 catch(
const Exception &e)
8556 Screen->Cursor = TCursor(-11);
8598 Screen->Cursor = TCursor(-2);
8601 catch(
const Exception &e)
8615 Screen->Cursor = TCursor(-11);
8652 OperateButton->Glyph->LoadFromResourceName(0,
"PauseGraphic");
8659 OperateButton->Glyph->LoadFromResourceName(0,
"RunGraphic");
8668 OperateButton->Glyph->LoadFromResourceName(0,
"RunGraphic");
8695 if((LeftExcess > 0) && (RightExcess > 0))
8697 else if((LeftExcess > 0) && (RightExcess <= 0))
8700 else if((LeftExcess <= 0) && (RightExcess > 0))
8708 if((TopExcess > 0) && (BotExcess > 0))
8710 else if((TopExcess > 0) && (BotExcess <= 0))
8713 else if((TopExcess <= 0) && (BotExcess > 0))
8723 ZoomButton->Glyph->LoadFromResourceName(0,
"ZoomIn");
8725 Screen->Cursor = TCursor(-2);
8729 catch(
const Exception &e)
8743 Screen->Cursor = TCursor(-11);
8766 Screen->Cursor = TCursor(-2);
8770 catch(
const Exception &e)
8798 catch(
const Exception &e)
8814 catch(
const Exception &e)
8835 ShowMessage(
"Please be aware when pasting that anything inside the pasted area will be overwritten.\n\nThis warning will not be shown again.");
8846 catch(
const Exception &e)
8869 TRect NewSelectRect(TLHCH, TLHCV, BRHCH, BRHCV);
8902 catch(
const Exception &e)
8921 catch(
const Exception &e)
8940 catch(
const Exception &e)
8988 int MidVPosAfterFlip = ((VerSum * 16) + 15) - MidVPosBeforeFlip;
8996 catch(
const Exception &e)
9044 int MidHPosAfterMirror = ((HorSum * 16) + 15) - MidHPosBeforeMirror;
9046 if(LeftPosAfterMirror < (
SelectRect.left * 16))
9056 catch(
const Exception &e)
9109 int MidVPosAfterFlip = ((VerSum * 16) + 15) - MidVPosBeforeFlip;
9121 int MidHPosAfterMirror = ((HorSum * 16) + 15) - MidHPosBeforeMirror;
9123 if(LeftPosAfterMirror < (
SelectRect.left * 16))
9135 catch(
const Exception &e)
9148 Screen->Cursor = TCursor(-11);
9165 int button = Application->MessageBox
9166 (L
"Original selection adjusted to make it square. 'OK' to keep this selection or 'Cancel' to make a new selection",
9167 L
"Left click and hold here to move this message box", MB_OKCANCEL);
9168 if(button == IDCANCEL)
9176 Screen->Cursor = TCursor(-2);
9213 if(IATVecPair.second != IATVecPair.first)
9231 if((TextPtr->HPos >= LowSelectHPos) && (TextPtr->HPos < HighSelectHPos) && (TextPtr->VPos >= LowSelectVPos) && (TextPtr->VPos < HighSelectVPos))
9238 bool SelectVectorNamedElement =
false;
9239 AnsiString SelectTextString;
9244 SelectVectorNamedElement =
true;
9248 if(SelectVectorNamedElement)
9250 SelectTextString =
"##**" + TextPtr->TextString;
9254 SelectTextString = TextPtr->TextString;
9256 TTextItem TextItem(TextPtr->HPos, TextPtr->VPos, SelectTextString, TextPtr->Font);
9265 for(TTrack::TUserGraphicVector::iterator UserGraphicPtr =
Track->
UserGraphicVector.begin(); UserGraphicPtr < Track->UserGraphicVector.end();
9268 if((UserGraphicPtr->HPos >= LowSelectHPos) && ((UserGraphicPtr->HPos + UserGraphicPtr->Width) < HighSelectHPos) && (UserGraphicPtr->VPos >=
9269 LowSelectVPos) && ((UserGraphicPtr->VPos + UserGraphicPtr->Height) < HighSelectVPos))
9308 int MidHPosAfterRotate = ((
SelectRect.bottom * 16) - 1) + (
SelectRect.left * 16) - MidVPosBeforeRotate;
9315 Screen->Cursor = TCursor(-2);
9320 catch(
const Exception &e)
9334 Screen->Cursor = TCursor(-11);
9351 int button = Application->MessageBox
9352 (L
"Original selection adjusted to make it square. 'OK' to keep this selection or 'Cancel' to make a new selection",
9353 L
"Left click and hold here to move this message box", MB_OKCANCEL);
9354 if(button == IDCANCEL)
9362 Screen->Cursor = TCursor(-2);
9399 if(IATVecPair.second != IATVecPair.first)
9417 if((TextPtr->HPos >= LowSelectHPos) && (TextPtr->HPos < HighSelectHPos) && (TextPtr->VPos >= LowSelectVPos) && (TextPtr->VPos < HighSelectVPos))
9424 bool SelectVectorNamedElement =
false;
9425 AnsiString SelectTextString;
9430 SelectVectorNamedElement =
true;
9434 if(SelectVectorNamedElement)
9436 SelectTextString =
"##**" + TextPtr->TextString;
9440 SelectTextString = TextPtr->TextString;
9442 TTextItem TextItem(TextPtr->HPos, TextPtr->VPos, SelectTextString, TextPtr->Font);
9451 for(TTrack::TUserGraphicVector::iterator UserGraphicPtr =
Track->
UserGraphicVector.begin(); UserGraphicPtr < Track->UserGraphicVector.end();
9454 if((UserGraphicPtr->HPos >= LowSelectHPos) && ((UserGraphicPtr->HPos + UserGraphicPtr->Width) < HighSelectHPos) && (UserGraphicPtr->VPos >=
9455 LowSelectVPos) && ((UserGraphicPtr->VPos + UserGraphicPtr->Height) < HighSelectVPos))
9495 int MidVPosAfterRotate = ((
SelectRect.bottom * 16) - 1) + (
SelectRect.left * 16) - MidHPosBeforeRotate;
9501 Screen->Cursor = TCursor(-2);
9506 catch(
const Exception &e)
9526 catch(
const Exception &e)
9545 catch(
const Exception &e)
9563 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Set values or leave blank for no change";
9566 ShowMessage(
"Note: length value will apply to each element's track within the selection.\n\nThis message will not be shown again.");
9576 catch(
const Exception &e)
9594 bool FoundFlag =
false;
9638 catch(
const Exception &e)
9668 catch(
const Exception &e)
9700 bool CheckLocationsExistInRailwayTrue =
true;
9704 Screen->Cursor = TCursor(-11);
9705 std::ifstream TTBLFile(AnsiString(
TimetableDialog->FileName).c_str(), std::ios_base::binary);
9706 if(TTBLFile.is_open())
9708 bool SessionFileFalse =
false;
9716 ShowMessage(
"Failed to open timetable file, make sure it's not open in another application");
9718 Screen->Cursor = TCursor(-2);
9721 ShowMessage(
"Timetable preliminary integrity check failed - unable to load");
9726 catch(
const Exception &e)
9751 AnsiString LocName =
"";
9756 if((LocName ==
"") && (Train.
MidElement > -1))
9776 if((NextElementPosition > -1) && (NextEntryPos > -1))
9791 if((LocName ==
"") && (Train.
MidElement > -1))
9798 catch(
const Exception &e)
9822 AnsiString LocName =
"";
9827 if((LocName ==
"") && (Train.
MidElement > -1))
9835 if((LocName ==
"") && (Train.
MidElement > -1))
9865 int NextElementPos = -1;
9866 int NextEntryPos = -1;
9882 if((NextElementPos > -1) && (NextEntryPos > -1))
9916 catch(
const Exception &e)
9934 AnsiString LocName =
"";
9939 if((LocName ==
"") && (Train.
MidElement > -1))
9947 if((LocName ==
"") && (Train.
MidElement > -1))
9954 catch(
const Exception &e)
9983 int NextElementPos = -1;
9984 int NextEntryPos = -1;
9990 if((NextElementPos > -1) && (NextEntryPos > -1))
10010 catch(
const Exception &e)
10023 TTrain *TrainToBeJoinedBy;
10036 ShowMessage(
"Can't join two trains when both are without power");
10040 AnsiString TrainToBeJoinedByHeadCode = TrainToBeJoinedBy->
HeadCode;
10042 double OtherBrakeForce = TrainToBeJoinedBy->
MaxBrakeRate * TrainToBeJoinedBy->
Mass;
10044 double CombinedBrakeRate = (OtherBrakeForce + OwnBrakeForce) / (TrainToBeJoinedBy->
Mass + ThisTrain.
Mass);
10045 ThisTrain.
Mass += TrainToBeJoinedBy->
Mass;
10052 AnsiString LocName =
"";
10057 if((LocName ==
"") && (ThisTrain.
MidElement > -1))
10061 if((LocName ==
"") && ThisTrain.
LeadElement > -1)
10065 if((LocName ==
"") && (ThisTrain.
MidElement > -1))
10099 catch(
const Exception &e)
10129 AnsiString LocName =
"";
10134 if((LocName ==
"") && (Train.
MidElement > -1))
10142 if((LocName ==
"") && (Train.
MidElement > -1))
10158 catch(
const Exception &e)
10189 catch(
const Exception &e)
10205 if(NextElementPos < 0)
10207 throw Exception(
"Error, no element in front in PassRedSignalMenuItemClick");
10218 throw Exception(
"Error, next element not a signal type in PassRedSignalMenuItemClick");
10232 catch(
const Exception &e)
10258 int NextElementPos = -1;
10260 int NextEntryPos = -1;
10266 if((NextElementPos > -1) && (NextEntryPos > -1))
10275 catch(
const Exception &e)
10294 UnicodeString Message = UnicodeString(Train.
HeadCode) +
" will be removed from the railway - proceed?";
10295 int button = Application->MessageBox(Message.c_str(), L
"Please confirm", MB_YESNO);
10308 AnsiString LocName =
"";
10313 if((LocName ==
"") && (Train.
MidElement > -1))
10321 if((LocName ==
"") && (Train.
MidElement > -1))
10419 catch(
const Exception &e)
10434 Application->Terminate();
10448 catch(
const Exception &e)
10462 UnicodeString MessageStr =
10463 "Note that leaving the track unlinked will cause preferred directions to be lost on reloading. Prevent by linking the track then resaving. Do you still wish to exit?";
10464 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
10474 UnicodeString MessStr =
"";
10477 MessStr = UnicodeString(
"The railway and the timetable have both changed, exit without saving either?");
10481 MessStr = UnicodeString(
"The railway has changed, exit without saving?");
10485 MessStr = UnicodeString(
"The timetable has changed, exit without saving?");
10487 int button = Application->MessageBox(MessStr.c_str(), L
"Please confirm", MB_YESNO);
10500 UnicodeString MessageStr =
"Please note that the session will be lost if it hasn't been saved. Do you still wish to exit?";
10503 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
10522 catch(
const Exception &e)
10536 if((Shift.Contains(ssAlt)) && (Shift.Contains(ssCtrl)))
10549 else if(Key ==
'3')
10561 else if(Key ==
'4')
10565 else if(Key ==
'5')
10567 TMsgDlgButtons Buttons;
10568 Buttons << mbYes << mbNo;
10569 if(MessageDlg(
"Do you wish to allow facing signals next to bridges? If so please be aware that routes cannot be truncated to these signals.", mtWarning, Buttons, 0) == mrYes)
10579 else if(Shift.Contains(ssCtrl) && !Shift.Contains(ssShift) && !Shift.Contains(ssAlt))
10583 else if(Shift.Contains(ssShift) && !Shift.Contains(ssCtrl) && !Shift.Contains(ssAlt))
10596 if((Key != VK_SHIFT) && (Key != VK_CONTROL))
10613 else if(Key == VK_DOWN)
10618 else if(Key == VK_LEFT)
10623 else if(Key == VK_RIGHT)
10628 else if(Key == VK_HOME)
10634 else if(Key == VK_END)
10639 else if(Key == VK_END)
10653 if(Shift.Contains(ssShift) && !Shift.Contains(ssAlt) && !Shift.Contains(ssCtrl) &&
NewHomeButton->Enabled &&
NewHomeButton->Visible)
10664 if(!Shift.Contains(ssCtrl))
10723 if(Key ==
'S' || Key ==
's')
10734 if(Shift.Contains(ssShift))
10750 if(Shift.Contains(ssShift) && !Shift.Contains(ssCtrl) && !Shift.Contains(ssAlt))
10797 if(Shift.Contains(ssCtrl) && !Shift.Contains(ssShift) && !Shift.Contains(ssAlt))
10802 if(Key ==
'S' || Key ==
's')
10808 if(!Shift.Contains(ssCtrl) && !Shift.Contains(ssShift) && !Shift.Contains(ssAlt))
10820 if(!Shift.Contains(ssShift) && !Shift.Contains(ssCtrl))
10827 if(!Shift.Contains(ssShift) && Shift.Contains(ssCtrl))
10832 if(Key ==
'S' || Key ==
's')
10838 if(Shift.Contains(ssShift) && !Shift.Contains(ssCtrl))
10859 if(!Shift.Contains(ssShift) && !Shift.Contains(ssCtrl))
10866 if(Shift.Contains(ssShift) && !Shift.Contains(ssCtrl))
10872 if(Key ==
'S' || Key ==
's')
10877 else if(Key ==
'H' || Key ==
'h')
10891 if(Shift.Contains(ssShift) && !Shift.Contains(ssCtrl))
10961 if(
SaveTTButton->Enabled && (Key ==
'T' || Key ==
't'))
10986 if(
FloatingInfoMenu->Enabled && !Shift.Contains(ssAlt) && Shift.Contains(ssCtrl) && Shift.Contains(ssShift))
10988 if(Key ==
'I' || Key ==
'i')
10994 if(Key ==
'S' || Key ==
's')
10998 else if(Key ==
'T' || Key ==
't')
11008 catch(
const Exception &e)
11018 if((Key != VK_SHIFT) && (Key != VK_CONTROL))
11138 catch(
const Exception &e)
11151 Application->HelpKeyword(u
"Introduction");
11153 catch(
const Exception &e)
11163 const UnicodeString Link =
"http://www.railwayoperationsimulator.com";
11164 ::ShellExecute(Handle, NULL, (Link).c_str(), NULL, NULL, SW_SHOWNORMAL);
11187 catch(
const Exception &e)
11213 catch(
const Exception &e)
11239 catch(
const Exception &e)
11295 bool ErrorFlag =
false, TooBigFlag =
false;
11316 if(!ErrorFlag && !TooBigFlag)
11326 int KPH = (MPH * 1.609344) + 0.5;
11333 int MPH = (KPH * 0.621371) + 0.5;
11344 catch(
const EConvertError &ec)
11348 catch(
const Exception &e)
11383 bool ErrorFlag =
false, TooBigFlag =
false;
11404 if(!ErrorFlag && !TooBigFlag)
11414 int KW = (HP * 0.745699872) + 0.5;
11421 int HP = (KW * 1.340482574) + 0.5;
11432 catch(
const EConvertError &ec)
11436 catch(
const Exception &e)
11449 bool ErrorFlag =
false, TooBigFlag =
false;
11470 if(!ErrorFlag && !TooBigFlag)
11480 int KPH = (MPH * 1.609344) + 0.5;
11487 int MPH = (KPH * 0.621371) + 0.5;
11498 catch(
const EConvertError &ec)
11502 catch(
const Exception &e)
11516 bool ErrorFlag =
false, TooLongFlag =
false;
11519 for(
int x = 1; x <=
MileEdit->Text.Length(); x++)
11531 for(
int x = 1; x <=
ChainEdit->Text.Length(); x++)
11543 for(
int x = 1; x <=
YardEdit->Text.Length(); x++)
11555 TooLongFlag =
true;
11558 if(!ErrorFlag && !TooLongFlag)
11560 int Miles = 0, Chains = 0, Yards = 0, Metres = 0;
11573 Metres = int((Miles * 1609.344) + (Chains * 20.1168) + (Yards * 0.9144) + 0.5);
11582 catch(
const EConvertError &ec)
11586 catch(
const Exception &e)
11617 catch(
const Exception &e)
11653 "Changes have been made to the timetable clock - you may wish to save a session before resuming operation.\n\nTo cancel all changes re-click the 'Adjust the timetable clock' button then click the reset button BEFORE resuming operation.";
11660 catch(
const Exception &e)
11678 catch(
const Exception &e)
11697 catch(
const Exception &e)
11716 catch(
const Exception &e)
11735 catch(
const Exception &e)
11754 catch(
const Exception &e)
11773 catch(
const Exception &e)
11792 catch(
const Exception &e)
11811 catch(
const Exception &e)
11829 catch(
const Exception &e)
11843 double TTClockIncrement = 1.0 / 24;
11849 catch(
const Exception &e)
11863 double TTClockIncrement = 1.0 / 144;
11869 catch(
const Exception &e)
11883 double TTClockIncrement = 1.0 / 1440;
11889 catch(
const Exception &e)
11930 catch(
const Exception &e)
11944 InfoPanel->Caption =
"PRE-START: Presetting automatic signal routes";
11955 Screen->Cursor = TCursor(-11);
11957 bool PointsChanged, AtLeastOneSet =
false;
11958 int LastIteratorValue = 0;
11965 AtLeastOneSet =
true;
11981 ShowMessage(
"No presettable automatic signal routes are available");
11983 Screen->Cursor = TCursor(-2);
11986 catch(
const Exception &e)
12000 int DispW = (
Interface->Width - 64 - 16) / 16;
12002 int DispH = (
Interface->Height - 192) / 16;
12034 catch(
const Exception &e)
12064 catch(
const Exception &e)
12090 SigImagePanel->Caption =
"Signals will be on the right hand side of the track";
12095 std::ofstream SigFile((
CurDir +
"\\Signal.hnd").c_str());
12098 ShowMessage(
"Failed to store right hand signal setting, program will default to left hand signals when next loaded");
12116 SigImagePanel->Caption =
"Signals will be on the left hand side of the track";
12121 std::ofstream SigFile((
CurDir +
"\\Signal.hnd").c_str());
12133 catch(
const Exception &e)
12152 bool TooBigFlag =
false, BadCharsFlag =
false;
12157 for(
int x = 1; x <=
MTBFEditBox->Text.Length(); x++)
12161 BadCharsFlag =
true;
12174 ShowMessage(
"Maximum value allowed is 10,000");
12183 ShowMessage(
"Value must be a whole number with no special characters");
12200 catch(
const Exception &e)
12218 "Values can only be entered or changed in Pre-Start mode\ni.e. after selecting 'Operate railway' but before clicking 'Run'");
12222 catch(
const Exception &e)
12254 catch(
const Exception &e)
12280 catch(
const Exception &e)
12296 catch(
const Exception &e)
12317 catch(
const Exception &e)
12334 catch(
const Exception &e)
12351 catch(
const Exception &e)
12367 ShowMessage(
"No boxes ticked!");
12371 Screen->Cursor = TCursor(-11);
12372 AnsiString TTTitle;
12386 ShowMessage(
"Analysis complete and file created");
12391 Screen->Cursor = TCursor(-2);
12394 catch(
const Exception &e)
12436 int WidthNum = int(
MainScreen->Width / 160) + 1;
12437 int HeightNum = int(
MainScreen->Height / 144) + 1;
12438 for(
int x = 0; x < WidthNum; x++)
12440 for(
int y = 0; y < HeightNum; y++)
12553 bool BreakFlag =
false;
12655 ZoomButton->Glyph->LoadFromResourceName(0,
"ZoomOut");
12681 InfoPanel->Caption =
"CONNECTING GAPS: Click on connecting element";
12697 UnicodeString MessageStr =
"The railway has changed, close it without saving?";
12698 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
12745 std::ifstream VecFile(FileName);
12747 if(VecFile.is_open())
12767 bool GraphicsFollow =
false;
12768 int NumberOfActiveElements;
12781 if(!(EveryPrefDir->CheckOnePrefDir(0, NumberOfActiveElements, VecFile)))
12812 TDateTime First, Second;
12813 bool Finished =
false;
12815 First = TDateTime::CurrentDateTime();
12816 double TimeVal1 = 86400000 * double(First);
12820 Second = TDateTime::CurrentDateTime();
12821 double TimeVal2 = 86400000 * double(Second);
12822 if((TimeVal2 - TimeVal1) > Msec)
12872 if((LinkNumber1 == 1) || (LinkNumber1 == 3) || (LinkNumber1 == 7) || (LinkNumber1 == 9))
12880 if((LinkNumber2 == 1) || (LinkNumber2 == 3) || (LinkNumber2 == 7) || (LinkNumber2 == 9))
13032 InfoPanel->Caption =
"Select an option from the File, Mode or Help menus";
13188 InfoPanel->Caption =
"PREFERRED DIRECTION SETTING: Select preferred direction start location (right click to erase)";
13250 MTBFLabel->Caption =
"Mean time between\ntrain failures in\ntimetable hours";
13264 OperateButton->Glyph->LoadFromResourceName(0,
"RunGraphic");
13291 ShowMessage(
"Performance logfile failed to open, logs won't be saved. Ensure that there is a folder named " +
PERFLOG_DIR_NAME +
13292 " in the folder where the 'Railway.exe' program file resides");
13333 OAListBox->Items->Add(L
"to locate train");
13338 OAListBox->Items->Add(L
"Left click and");
13339 OAListBox->Items->Add(L
"hold grey area");
13340 OAListBox->Items->Add(L
"to move panel");
13370 OperateButton->Glyph->LoadFromResourceName(0,
"RunGraphic");
13393 OAListBox->Items->Add(L
"to locate train");
13398 OAListBox->Items->Add(L
"Left click and");
13399 OAListBox->Items->Add(L
"hold grey area");
13400 OAListBox->Items->Add(L
"to move panel");
13414 MTBFLabel->Caption =
"Mean time between\ntrain failures in\ntimetable hours";
13423 MTBFLabel->Caption =
"Mean time between\ntrain failures in\ntimetable hours";
13460 InfoPanel->Caption =
"ADDING TRACK: Select element then left click to add it. Right click an element to remove it.";
13481 InfoPanel->Caption =
"ADDING GRAPHIC: Left click layout to add SELECTED graphic, right click to remove ANY graphic.";
13486 InfoPanel->Caption =
"SELECTING USER GRAPHIC: Select the graphic file then add as many as necessary to the layout.";
13490 int HLoc, VLoc, Count;
13492 if(div(Count, 2).rem == 1)
13494 ShowMessage(
"Can't connect, there are an odd number of gaps");
13509 ShowMessage(
"Error - Even number of gaps but all set after first call to HighLightOneGap");
13519 InfoPanel->Caption =
"CONNECTING GAPS: Click on connecting gap";
13526 InfoPanel->Caption =
"ADDING/EDITING TEXT: Left click to add, right click first letter to erase, or left click first letter to edit)";
13541 InfoPanel->Caption =
"MOVING TEXT OR GRAPHIC: If text left click first letter, if graphic left click anywhere, then drag";
13548 InfoPanel->Caption =
"NAMING LOCATIONS: Click on location element to add or change name";
13556 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Select first location (only non-default elements marked)";
13567 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Select next location";
13569 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Continue or set values (overall length), or right click to cancel/truncate";
13581 InfoPanel->Caption =
"SELECTING: Select area - click left mouse && drag";
13591 InfoPanel->Caption =
"COPYING: Left click in selection && drag";
13615 bool EraseSuccessfulFlag, NeedToLink =
false, TextChangesMade =
false, GraphicChangesMade =
false; ;
13616 int ErasedTrackVectorPosition;
13617 Screen->Cursor = TCursor(-11);
13619 InfoPanel->Caption =
"CUT PROCESSING: Please do not click the mouse";
13626 if(EraseSuccessfulFlag)
13628 if(ErasedTrackVectorPosition > -1)
13638 int HighSelectVPos =
SelectRect.bottom * 16;
13644 if((TextPtr->HPos >= LowSelectHPos) && (TextPtr->HPos < HighSelectHPos) && (TextPtr->VPos >= LowSelectVPos) && (TextPtr->VPos <
13650 TextChangesMade =
true;
13660 if((GraphicPtr->HPos >= LowSelectHPos) && ((GraphicPtr->HPos + GraphicPtr->Width) < HighSelectHPos) && (GraphicPtr->VPos >= LowSelectVPos)
13661 && ((GraphicPtr->VPos + GraphicPtr->Height) < HighSelectVPos))
13664 GraphicChangesMade =
true;
13671 Screen->Cursor = TCursor(-2);
13676 InfoPanel->Caption =
"CUTTING: Left click in selection && drag";
13692 if(NeedToLink || TextChangesMade || GraphicChangesMade)
13707 bool NeedToLink =
false;
13708 bool TrackLinkingRequiredFlag;
13709 Screen->Cursor = TCursor(-11);
13711 InfoPanel->Caption =
"PASTING: Please wait";
13718 bool TrackEraseSuccessfulFlag;
13719 int ErasedTrackVectorPosition;
13721 for(
int x = LowSelectHLoc; x < HighSelectHLoc; x++)
13723 for(
int y = LowSelectVLoc; y < HighSelectVLoc; y++)
13726 if(ErasedTrackVectorPosition > -1)
13741 if((TextPtr->HPos >= LowSelectHPos) && (TextPtr->HPos < HighSelectHPos) && (TextPtr->VPos >= LowSelectVPos) && (TextPtr->VPos <
13756 if((GraphicPtr->HPos >= LowSelectHPos) && ((GraphicPtr->HPos + GraphicPtr->Width) < HighSelectHPos) && (GraphicPtr->VPos >= LowSelectVPos)
13757 && ((GraphicPtr->VPos + GraphicPtr->Height) < HighSelectVPos))
13778 bool InternalChecks =
false;
13782 TrackLinkingRequiredFlag, InternalChecks);
13798 if(TrackLinkingRequiredFlag)
13806 TextPtr->HPos += HDiff * 16;
13807 TextPtr->VPos += VDiff * 16;
13808 AnsiString TempString = TextPtr->TextString;
13824 if(TextPtr->TextString.SubString(1, 4) ==
"##**")
13826 TempString = TextPtr->TextString.SubString(5, TextPtr->TextString.Length());
13829 TextPtr->TextString =
"";
13841 for(TTrack::TUserGraphicVector::iterator GraphicPtr =
Track->
SelectGraphicVector.begin(); GraphicPtr < Track->SelectGraphicVector.end();
13844 GraphicPtr->HPos += HDiff * 16;
13845 GraphicPtr->VPos += VDiff * 16;
13858 Screen->Cursor = TCursor(-2);
13872 UnicodeString MessageStr =
"Selected area will be deleted - proceed?";
13873 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
13878 bool EraseSuccessfulFlag, NeedToLink =
false, TextChangesMade =
false, GraphicChangesMade =
false;
13879 int ErasedTrackVectorPosition;
13880 Screen->Cursor = TCursor(-11);
13882 InfoPanel->Caption =
"DELETING: Please wait";
13889 if(EraseSuccessfulFlag)
13891 if(ErasedTrackVectorPosition > -1)
13901 int HighSelectVPos =
SelectRect.bottom * 16;
13907 AnsiString Check = TextPtr->TextString;
13908 if((TextPtr->HPos >= LowSelectHPos) && (TextPtr->HPos < HighSelectHPos) && (TextPtr->VPos >= LowSelectVPos) && (TextPtr->VPos <
13914 TextChangesMade =
true;
13933 if((GraphicPtr->HPos >= LowSelectHPos) && ((GraphicPtr->HPos + GraphicPtr->Width) < HighSelectHPos) && (GraphicPtr->VPos >= LowSelectVPos)
13934 && ((GraphicPtr->VPos + GraphicPtr->Height) < HighSelectVPos))
13939 if((UserGraphicPtr->HPos == GraphicPtr->HPos) && (UserGraphicPtr->VPos == GraphicPtr->VPos) &&
13940 (UserGraphicPtr->Width == GraphicPtr->Width) && (UserGraphicPtr->Height == GraphicPtr->Height) &&
13941 (UserGraphicPtr->FileName == GraphicPtr->FileName))
13944 GraphicChangesMade =
true;
13961 if(NeedToLink || TextChangesMade || GraphicChangesMade)
13965 Screen->Cursor = TCursor(-2);
14017 bool LeadingPointsAtLastElement =
false;
14020 if(LeadingPointsAtLastElement)
14022 InfoPanel->Caption =
"PREFERRED DIRECTION SETTING: Can't end on leading points, select next location or truncate";
14027 InfoPanel->Caption =
"PREFERRED DIRECTION SETTING: Select next preferred direction location (right click to truncate)";
14032 InfoPanel->Caption =
"PREFERRED DIRECTION SETTING: Add selection or select next location (right click to truncate)";
14047 InfoPanel->Caption =
"SELECTING: Select area - click left mouse && drag";
14087 OperateButton->Glyph->LoadFromResourceName(0,
"PauseGraphic");
14130 Display->
PerformanceLog(15, TimeMessage +
"Timetable clock speed changed to one sixteenth normal");
14135 if(TTClockTimeChange > 0.000347)
14138 int MinsIncrease = ((TTClockTimeChange * 1440) + 0.5);
14139 int HoursIncrease = 0;
14140 while(MinsIncrease >= 60)
14143 MinsIncrease -= 60;
14145 if(HoursIncrease == 0)
14146 TimeMessage +=
"Timetable clock incremented by " + AnsiString(MinsIncrease) +
"m";
14147 else if(MinsIncrease == 0)
14148 TimeMessage +=
"Timetable clock incremented by " + AnsiString(HoursIncrease) +
"h";
14150 TimeMessage +=
"Timetable clock incremented by " + AnsiString(HoursIncrease) +
"h " + AnsiString(MinsIncrease) +
"m";
14161 MTBFLabel->Caption =
"Mean time between\ntrain failures in\ntimetable hours";
14169 MTBFLabel->Caption =
"Mean time between\ntrain failures in\ntimetable hours";
14178 OperateButton->Glyph->LoadFromResourceName(0,
"RunGraphic");
14206 float LockDelay = 120.0;
14212 bool BreakFlag =
false;
14216 if((TTClockTime - LRVIT->LockStartTime) > TDateTime(LockDelay / 86400))
14219 AnsiString(LRVIT->LastTrackVectorPosition));
14220 while(Route.
LastElementPtr(9)->GetTrackVectorPosition() != LRVIT->TruncateTrackVectorPosition)
14233 if(Route.
LastElementPtr(17)->GetTrackVectorPosition() == LRVIT->TruncateTrackVectorPosition)
14272 int TempLockedVectorNumber;
14282 if(((TTClockTime - AutoSigVectorIT->PassoutTime) > TDateTime(AutoSigVectorIT->FirstDelay / 86400)) && (AutoSigVectorIT->AccessNumber == 0))
14285 AutoSigVectorIT->AccessNumber++;
14288 if(((TTClockTime - AutoSigVectorIT->PassoutTime) > TDateTime(AutoSigVectorIT->SecondDelay / 86400)) && (AutoSigVectorIT->AccessNumber == 1))
14291 AutoSigVectorIT->AccessNumber++;
14294 if(((TTClockTime - AutoSigVectorIT->PassoutTime) > TDateTime(AutoSigVectorIT->ThirdDelay / 86400)) && (AutoSigVectorIT->AccessNumber == 2))
14297 AutoSigVectorIT->AccessNumber++;
14305 if(AutoSigVectorIT->AccessNumber > 2)
14320 TPoint MousePoint = Mouse->CursorPos;
14321 int ScreenX = MousePoint.x -
MainScreen->ClientOrigin.x;
14322 int ScreenY = MousePoint.y -
MainScreen->ClientOrigin.y;
14324 if((ScreenX > (
MainScreen->Width - 1)) || (ScreenY > (
MainScreen->Height - 1)) || (ScreenX < 0) || (ScreenY < 0))
14334 ((MousePoint.y - ClientOrigin.y) >=
PerformancePanel->Top) && ((MousePoint.y - ClientOrigin.y) <=
14346 ((MousePoint.y - ClientOrigin.y) >=
OperatorActionPanel->Top) && ((MousePoint.y - ClientOrigin.y) <=
14358 ((MousePoint.y - ClientOrigin.y) >=
TimetableEditPanel->Top) && ((MousePoint.y - ClientOrigin.y) <=
14367 AnsiString TrackFloat =
"", TrainStatusFloat =
"", TrainTTFloat =
"";
14369 bool ShowTrackFloatFlag =
false, ShowTrainStatusFloatFlag =
false, ShowTrainTTFloatFlag =
false;
14381 bool ActiveTrackFoundFlag =
false, InactiveTrackFoundFlag =
false, TwoTrack =
false;
14382 AnsiString Length01Str =
"", Length23Str =
"", SpeedLimit01Str =
"", SpeedLimit23Str =
"";
14383 AnsiString StationEntryStopLinkPos1Str =
"", StationEntryStopLinkPos2Str =
"";
14384 AnsiString ATrackSN =
"", ATrackTN =
"", IATrackSN =
"", LengthAndSpeedCaption =
"";
14385 AnsiString SigAspectString =
"";
14389 if(InactiveTrackFoundFlag)
14394 if(ActiveTrackFoundFlag)
14401 if((ATrackTN !=
"") && (!InactiveTrackFoundFlag || ((InactiveTrackElement.
TrackType !=
Platform) &&
14405 ShowMessage(
"Error - Track has timetable name without corresponding plat/named loc");
14410 ShowMessage(
"Error - plat/named loc and track have different names, or plat/named loc named but not track");
14416 Length01Str = AnsiString(ActiveTrackElement.
Length01);
14417 if(Length01Str ==
"-1")
14418 Length01Str =
"Not Set";
14419 SpeedLimit01Str = AnsiString(ActiveTrackElement.
SpeedLimit01);
14420 if(SpeedLimit01Str ==
"-1")
14421 SpeedLimit01Str =
"Not Set";
14424 Length23Str = AnsiString(ActiveTrackElement.
Length23);
14425 if(Length23Str ==
"-1")
14426 Length23Str =
"Not Set";
14427 SpeedLimit23Str = AnsiString(ActiveTrackElement.
SpeedLimit23);
14428 if(SpeedLimit23Str ==
"-1")
14429 SpeedLimit23Str =
"Not Set";
14432 LengthAndSpeedCaption =
"Straight track length = " + Length01Str +
" m" +
'\n' +
"Diverging track length = " + Length23Str +
" m" +
'\n' +
14433 "Straight track speed limit = " + SpeedLimit01Str +
" km/h" +
'\n' +
"Diverging track speed limit = " + SpeedLimit23Str +
" km/h";
14437 LengthAndSpeedCaption =
"Left diverging track length = " + Length01Str +
" m" +
'\n' +
"Right diverging track length = " + Length23Str +
14438 " m" +
'\n' +
"Left diverging track speed limit = " + SpeedLimit01Str +
" km/h" +
'\n' +
"Right diverging track Speed Limit = " +
14439 SpeedLimit23Str +
" km/h";
14444 if((ActiveTrackElement.
SpeedTag == 15) || (ActiveTrackElement.
SpeedTag == 46))
14446 LengthAndSpeedCaption =
"Horizontal track length = " + Length01Str +
" m" +
'\n' +
"Other track length = " + Length23Str +
" m" +
'\n' +
14447 "Horizontal track speed limit = " + SpeedLimit01Str +
" km/h" +
'\n' +
"Other track speed limit = " + SpeedLimit23Str +
" km/h";
14449 else if(ActiveTrackElement.
SpeedTag == 47)
14451 LengthAndSpeedCaption =
"Horizontal track length = " + Length23Str +
" m" +
'\n' +
"Other track length = " + Length01Str +
" m" +
'\n' +
14452 "Horizontal track speed limit = " + SpeedLimit23Str +
" km/h" +
'\n' +
"Other track speed limit = " + SpeedLimit01Str +
" km/h";
14454 else if(ActiveTrackElement.
SpeedTag == 45)
14456 LengthAndSpeedCaption =
"Vertical track length = " + Length01Str +
" m" +
'\n' +
"Other track length = " + Length23Str +
" m" +
'\n' +
14457 "Vertical track speed limit = " + SpeedLimit01Str +
" km/h" +
'\n' +
"Other track speed limit = " + SpeedLimit23Str +
" km/h";
14459 else if(ActiveTrackElement.
SpeedTag == 44)
14461 LengthAndSpeedCaption =
"Vertical track length = " + Length23Str +
" m" +
'\n' +
"Other track length = " + Length01Str +
" m" +
'\n' +
14462 "Vertical track speed limit = " + SpeedLimit23Str +
" km/h" +
'\n' +
"Other track speed limit = " + SpeedLimit01Str +
" km/h";
14464 else if(ActiveTrackElement.
SpeedTag == 16)
14466 LengthAndSpeedCaption =
"Top left to bottom right track length = " + Length01Str +
" m" +
'\n' +
"Other track length = " + Length23Str +
14467 " m" +
'\n' +
"Top left to bottom right track speed limit = " + SpeedLimit01Str +
" km/h" +
'\n' +
"Other track speed limit = " +
14468 SpeedLimit23Str +
" km/h";
14473 LengthAndSpeedCaption =
"Top track length = " + Length01Str +
" m" +
'\n' +
"Bottom track length = " + Length23Str +
" m" +
'\n' +
14474 "Top track speed limit = " + SpeedLimit01Str +
" km/h" +
'\n' +
"Bottom track speed limit = " + SpeedLimit23Str +
" km/h";
14479 LengthAndSpeedCaption =
"Track length = " + Length01Str +
" m" +
'\n' +
"Track speed limit = " + SpeedLimit01Str +
" km/h";
14482 if(ActiveTrackFoundFlag)
14486 ShowTrackFloatFlag =
true;
14489 TrackFloat =
"Location = " + ATrackTN +
'\n' + LengthAndSpeedCaption +
'\n' +
"ID = " + AnsiString(ActiveTrackElement.
ElementID);
14491 else if(ATrackSN !=
"")
14493 TrackFloat =
"Location = " + ATrackSN +
'\n' + LengthAndSpeedCaption +
'\n' +
"ID = " + AnsiString(ActiveTrackElement.
ElementID);
14496 else if(InactiveTrackFoundFlag)
14498 TrackFloat =
"Location unnamed\n" + LengthAndSpeedCaption +
'\n' +
"ID = " + AnsiString(ActiveTrackElement.
ElementID);
14503 TrackFloat = LengthAndSpeedCaption +
'\n' +
"Track Element ID = " + AnsiString(ActiveTrackElement.
ElementID);
14509 SigAspectString =
"\nThree-aspect signal";
14513 SigAspectString =
"\nTwo-aspect signal";
14517 SigAspectString =
"\nGround signal";
14521 SigAspectString =
"\nFour-aspect signal";
14523 TrackFloat += SigAspectString;
14526 else if(InactiveTrackFoundFlag)
14529 ShowTrackFloatFlag =
true;
14532 if(IATrackSN ==
"")
14534 TrackFloat =
"Location unnamed\nID = " + AnsiString(InactiveTrackElement.
ElementID);
14538 TrackFloat =
"Location = " + IATrackSN +
'\n' +
"ID = " + AnsiString(InactiveTrackElement.
ElementID);
14543 TrackFloat =
"ID = " + AnsiString(InactiveTrackElement.
ElementID);
14553 AnsiString FormatOneDPStr =
"####0.0";
14554 AnsiString FormatNoDPStr =
"#######0";
14556 AnsiString MaxBrakeStr =
"";
14557 AnsiString SpecialStr =
"", MaxSpeedStr =
"";
14567 ShowTrainStatusFloatFlag =
true;
14568 AnsiString HeadCode =
"", ServiceReferenceInfo =
"", Status =
"", CurrSpeedStr =
"", BrakePCStr =
"", NextStopStr =
"", TimeLeftStr =
"",
14569 TimeToNextMovementStr =
"", MassStr =
"", PowerStr =
"";
14571 MassStr = AnsiString::FormatFloat(FormatNoDPStr, ((
double)Train.
Mass) / 1000);
14572 PowerStr = AnsiString::FormatFloat(FormatNoDPStr, Train.
PowerAtRail / 1000 / 0.8);
14574 MaxSpeedStr =
"30";
14576 MaxSpeedStr = AnsiString::FormatFloat(FormatNoDPStr, Train.
MaxRunningSpeed);
14580 TDateTime TimeLeft;
14582 MaxBrakeStr = AnsiString::FormatFloat(FormatNoDPStr, (Train.
MaxBrakeRate * Train.
Mass / 9810));
14591 ServiceReferenceInfo =
"\nFirst service";
14594 ServiceReferenceInfo =
"\nRepeat service no. " + AnsiString(Train.
RepeatNumber);
14596 ServiceReferenceInfo =
"\nRepeat service no. " + AnsiString(Train.
RepeatNumber) +
" of ref. " +
14607 Status =
"Stopped on signaller's instruction";
14609 Status =
"Not in service";
14611 Status =
"Stopped at buffers";
14613 Status =
"Stopped at signal";
14615 Status =
"Stopped - forward track occupied";
14623 Status =
"Stopped without power - train failed";
14625 Status =
"Stopped without power";
14628 Status =
"Stopped - signal passed at danger";
14630 Status =
"Derailed";
14632 Status =
"Crashed";
14639 Status =
"Accelerating";
14646 if(BrakePCRate < 55)
14647 Status =
"Light braking";
14648 else if(BrakePCRate < 90)
14649 Status =
"Heavy braking";
14651 Status =
"Emergency braking";
14657 if(BrakePCRate < 55)
14658 Status =
"Light braking";
14659 else if(BrakePCRate < 90)
14660 Status =
"Heavy braking";
14662 Status =
"Emergency braking";
14668 Status =
"Accelerating";
14674 Status =
"Accelerating";
14676 ((Train.
ExitSpeedFull - Train.
ExitSpeedHalf) * (
double(ElapsedDeltaT - FirstHalfTimeDeltaT) / double(SecondHalfTimeDeltaT)));
14685 Status =
"Coasting - train failed";
14689 Status =
"Coasting - no power";
14695 Status =
"Constant speed";
14706 Status =
"Coasting - train failed";
14710 Status =
"Coasting - no power";
14716 Status =
"Constant speed";
14723 NextStopStr =
"At signaller's discretion";
14725 NextStopStr =
"None";
14731 SpecialStr =
"Train under signaller control" + AnsiString(
'\n');
14735 SpecialStr =
"Restricted speed - being called on" + AnsiString(
'\n');
14739 if(RemTimeHalf < 0)
14742 if(RemTimeFull < 0)
14744 if(RemTimeHalf > 0)
14745 TimeLeft = RemTimeHalf;
14747 TimeLeft = RemTimeFull;
14748 TimeToNextMovementStr =
"Time to next movement (sec) = " + TimeLeftStr.FormatFloat(FormatOneDPStr, TimeLeft);
14750 TimeToNextMovementStr =
"";
14754 MaxSpeedStr +
"km/h; Power " + PowerStr +
"kW" +
'\n' +
"Mass " + MassStr +
"Te; Brakes " + MaxBrakeStr +
"Te" +
'\n' + SpecialStr +
14755 Status +
'\n' +
"Next: " + NextStopStr;
14760 MaxSpeedStr +
"km/h; Power " + PowerStr +
"kW" +
'\n' +
"Mass " + MassStr +
"Te; Brakes " + MaxBrakeStr +
"Te" +
'\n' + SpecialStr +
14761 Status +
": " + CurrSpeedStr.FormatFloat(FormatNoDPStr, CurrSpeed) +
"km/h" +
'\n' +
"Next: " + NextStopStr;
14766 ShowTrainTTFloatFlag =
true;
14775 TrainStatusFloat =
"No trains expected";
14776 TrainTTFloat =
"No timetable";
14780 ShowTrainStatusFloatFlag =
true;
14782 ShowTrainTTFloatFlag =
true;
14789 (CTEIt->second.TrainDataEntryPtr->TrainOperatingDataVector.at(CTEIt->second.RepeatNumber).RunningEntry !=
NotStarted)))
14796 AnsiString ServiceReferenceInfo =
"";
14800 if(CTEIt->second.RepeatNumber == 0)
14803 ServiceReferenceInfo =
"\nFirst service of ref. " + TTDEPtr->
ServiceReference;
14805 ServiceReferenceInfo =
"\nFirst service";
14808 ServiceReferenceInfo =
"\nRepeat service no. " + AnsiString(CTEIt->second.RepeatNumber);
14810 ServiceReferenceInfo =
"\nRepeat service no. " + AnsiString(CTEIt->second.RepeatNumber) +
" of ref. " +
14816 ServiceReferenceInfo =
"\nService reference " + TTDEPtr->
ServiceReference;
14820 SpecialStr =
"\nTrain under signaller control";
14822 if(EntrySpeed > LineSpeedLimit)
14823 EntrySpeed = LineSpeedLimit;
14828 if(EntrySpeed > LineSpeedLimit)
14829 EntrySpeed = LineSpeedLimit;
14833 TDateTime TempTime = CTEIt->first;
14835 TrainStatusFloat = CTEIt->second.HeadCode +
": " + CTEIt->second.Description + ServiceReferenceInfo +
"\nEntry speed " +
14836 AnsiString::FormatFloat(FormatNoDPStr, EntrySpeed) +
"km/h" + SpecialStr +
"\nDelayed, was due at " +
14841 TDateTime TempTime = CTEIt->first;
14843 TrainStatusFloat = CTEIt->second.HeadCode +
": " + CTEIt->second.Description + ServiceReferenceInfo +
"\nEntry speed " +
14844 AnsiString::FormatFloat(FormatNoDPStr, EntrySpeed) +
"km/h" + SpecialStr +
"\nExpected at " +
14852 CTEIt->second.IncrementalMinutes, CTEIt->second.IncrementalDigits);
14863 AnsiString Caption;
14865 if(!ShowTrackFloatFlag && !ShowTrainStatusFloatFlag && !ShowTrainTTFloatFlag)
14871 else if(ShowTrackFloatFlag && !ShowTrainStatusFloatFlag && !ShowTrainTTFloatFlag)
14873 Caption = TrackFloat;
14875 else if(!ShowTrackFloatFlag && ShowTrainStatusFloatFlag && !ShowTrainTTFloatFlag)
14877 Caption = TrainStatusFloat;
14879 else if(ShowTrackFloatFlag && ShowTrainStatusFloatFlag && !ShowTrainTTFloatFlag)
14881 Caption = TrainStatusFloat +
'\n' +
'\n' + TrackFloat;
14883 else if(!ShowTrackFloatFlag && !ShowTrainStatusFloatFlag && ShowTrainTTFloatFlag)
14885 if(TrainStatusFloat ==
"No trains expected")
14886 Caption = TrainStatusFloat;
14888 Caption = TrainTTFloat;
14890 else if(ShowTrackFloatFlag && !ShowTrainStatusFloatFlag && ShowTrainTTFloatFlag)
14892 if(TrainStatusFloat ==
"No trains expected")
14893 Caption = TrainStatusFloat +
'\n' +
'\n' + TrackFloat;
14895 Caption = TrainTTFloat +
'\n' +
'\n' + TrackFloat;
14897 else if(!ShowTrackFloatFlag && ShowTrainStatusFloatFlag && ShowTrainTTFloatFlag)
14899 if(TrainStatusFloat ==
"No trains expected")
14900 Caption = TrainStatusFloat;
14902 Caption = TrainStatusFloat +
'\n' +
'\n' + TrainTTFloat;
14904 else if(ShowTrackFloatFlag && ShowTrainStatusFloatFlag && ShowTrainTTFloatFlag)
14906 if(TrainStatusFloat ==
"No trains expected")
14907 Caption = TrainStatusFloat +
'\n' +
'\n' + TrackFloat;
14909 Caption = TrainStatusFloat +
'\n' +
'\n' + TrainTTFloat +
'\n' +
'\n' + TrackFloat;
15007 InfoPanel->Caption =
"PRE-START: Route setting in progress";
15009 InfoPanel->Caption =
"OPERATING: Route setting in progress";
15131 bool Manual =
false;
15178 throw Exception(
"Failed to find a route at LC position HLoc = " + (AnsiString)H +
" VLoc = " + (AnsiString)V);
15183 if(RouteNumber > -1)
15217 bool SaveRailwayButtonsFlag =
true;
15226 SaveRailwayButtonsFlag =
false;
15243 SaveRailwayButtonsFlag =
false;
15251 SaveRailwayButtonsFlag =
false;
15304 bool ZoomFlag =
true, HomeFlag =
true, NewHomeFlag =
true, ScreenLeftFlag =
true, ScreenRightFlag =
true, ScreenUpFlag =
true, ScreenDownFlag =
true,
15305 TrackBuildPanelEnabledFlag =
true, PrefDirPanelEnabledFlag =
true, OperatingPanelEnabledFlag =
true, TimetablePanelEnabledFlag =
true;
15307 AnsiString TrackBuildPanelLabelCaptionStr =
"Build/modify";
15308 AnsiString PrefDirPanelLabelCaptionStr =
"Preferred direction selection";
15309 AnsiString OperatingPanelLabelCaptionStr =
"Operation";
15310 AnsiString TimetablePanelLabelCaptionStr =
"Timetable editor";
15315 ScreenLeftFlag =
false;
15317 ScreenRightFlag =
false;
15319 ScreenUpFlag =
false;
15321 ScreenDownFlag =
false;
15326 ScreenLeftFlag =
false;
15328 ScreenRightFlag =
false;
15330 ScreenUpFlag =
false;
15332 ScreenDownFlag =
false;
15338 NewHomeFlag =
false;
15339 ScreenLeftFlag =
false;
15340 ScreenRightFlag =
false;
15341 ScreenUpFlag =
false;
15342 ScreenDownFlag =
false;
15348 TrackBuildPanelEnabledFlag =
false;
15349 TrackBuildPanelLabelCaptionStr =
"Disabled";
15350 PrefDirPanelEnabledFlag =
false;
15351 PrefDirPanelLabelCaptionStr =
"Disabled";
15352 OperatingPanelEnabledFlag =
false;
15353 OperatingPanelLabelCaptionStr =
"Disabled";
15354 TimetablePanelEnabledFlag =
false;
15355 TimetablePanelLabelCaptionStr =
"Disabled";
15363 OperatingPanelEnabledFlag =
false;
15364 OperatingPanelLabelCaptionStr =
"Disabled";
15367 NewHomeFlag =
false;
15368 ScreenLeftFlag =
false;
15369 ScreenRightFlag =
false;
15370 ScreenUpFlag =
false;
15371 ScreenDownFlag =
false;
15385 NewHomeFlag =
false;
15386 ScreenLeftFlag =
false;
15387 ScreenRightFlag =
false;
15388 ScreenUpFlag =
false;
15389 ScreenDownFlag =
false;
15396 NewHomeFlag =
false;
15397 ScreenLeftFlag =
false;
15398 ScreenRightFlag =
false;
15399 ScreenUpFlag =
false;
15400 ScreenDownFlag =
false;
15408 NewHomeFlag =
false;
15409 ScreenLeftFlag =
false;
15410 ScreenRightFlag =
false;
15411 ScreenUpFlag =
false;
15412 ScreenDownFlag =
false;
15437 if(ScreenRightFlag)
15449 if(OperatingPanelEnabledFlag)
15453 if(TrackBuildPanelEnabledFlag)
15457 if(PrefDirPanelEnabledFlag)
15461 if(TimetablePanelEnabledFlag)
15480 bool CallOnValid =
false;
15486 CallOnValid =
true;
15579 Screen->Cursor = TCursor(-2);
15622 Caption =
"Railway: New railway under development";
15624 Caption =
"Railway: " +
RailwayTitle +
" under development";
15713 TFont *TempFont =
new TFont;
15715 TempFont->Style.Clear();
15716 TempFont->Name =
"MS Sans Serif";
15717 TempFont->Size = 10;
15719 TempFont->Charset = (TFontCharset)(0);
15825 if(NonPrefDirChangesMade)
15849 AnsiString CurrentDateTimeStr =
"", TimetableTimeStr =
"", SessionFileStr =
"";
15850 Screen->Cursor = TCursor(-11);
15851 CurrentDateTimeStr = TDateTime::CurrentDateTime().FormatString(
"dd-mm-yyyy hh.nn.ss");
15854 TimetableTimeStr = TimetableTimeStr.SubString(1, 2) +
'.' + TimetableTimeStr.SubString(4, 2) +
'.' + TimetableTimeStr.SubString(7, 2);
15857 SessionFileStr =
LoadSessionDialog->InitialDir +
"\\Session " + CurrentDateTimeStr +
"; Timetable time " + TimetableTimeStr +
"; " +
RailwayTitle +
15859 std::ofstream SessionFile(SessionFileStr.c_str());
15860 if(!(SessionFile.fail()))
15902 SessionFile.close();
15903 DeleteFile(SessionFileStr);
15904 Screen->Cursor = TCursor(-2);
15936 SessionFile.close();
15946 Screen->Cursor = TCursor(-2);
15949 catch(
const Exception &e)
15982 Screen->Cursor = TCursor(-11);
15987 if(!(SessionFile.fail()))
15994 int LastCharBeforeFloat = TempString.LastDelimiter(
'*');
15995 if((LastCharBeforeFloat == 0) || (LastCharBeforeFloat == TempString.Length()))
16002 AnsiString FloatStr = TempString.SubString(LastCharBeforeFloat + 1, TempString.Length() - LastCharBeforeFloat);
16018 bool GraphicsFollow =
false;
16034 SessionFile.close();
16035 Screen->Cursor = TCursor(-2);
16036 ShowMessage(
"Corruption in preferred direction section of the session file, session can't be loaded");
16044 SessionFile.close();
16045 Screen->Cursor = TCursor(-2);
16046 ShowMessage(
"Corruption in route section of the session file, session can't be loaded");
16058 if(TempString ==
"***BarriersDownVector***")
16066 SessionFile.close();
16067 Screen->Cursor = TCursor(-2);
16068 ShowMessage(
"Unable to load timetable section of the session file, session can't be loaded");
16075 SessionFile.close();
16076 Screen->Cursor = TCursor(-2);
16077 throw Exception(
"TimetableTitle null in LoadSession");
16095 ShowMessage(
"Performance logfile failed to open, logs won't be saved. Ensure that there is a folder named " +
PERFLOG_DIR_NAME +
16096 " in the folder where the 'Railway.exe' program file resides");
16102 SessionFile.get(TempChar);
16103 while(!SessionFile.eof() && ((TempChar ==
'\n') || (TempChar ==
'\0')))
16105 SessionFile.get(TempChar);
16107 if(SessionFile.eof())
16111 SessionFile.close();
16122 double PowerDouble;
16130 SessionFile.close();
16166 ShowMessage(
"Session file integrity check failed, unable to load session.");
16168 Screen->Cursor = TCursor(-2);
16172 catch(
const Exception &e)
16174 if((e.Message.Pos(
"esource") > 0) || (e.Message.Pos(
"arameter") > 0))
16176 Screen->Cursor = TCursor(-2);
16187 UnicodeString MessageStr =
16188 "Insufficient memory available to load the file, and partial load likely to be corrupt. Application will terminate. Try loading the session as the first action after reloading the program.";
16190 Application->MessageBox(MessageStr.c_str(), L
"Out of memory", MB_OK | MB_ICONERROR);
16191 Application->Terminate();
16262 if(OpMode ==
"PreStart")
16320 AnsiString OpMode =
"";
16327 else if((OpMode !=
"PreStart") && (OpMode !=
"NotPreStart"))
16559 SessionFile.close();
16560 SessionFile.open(SessionFileStr.c_str(), std::ios_base::app | std::ios_base::binary);
16574 ShowMessage(
"Failed to open temporary timetable file. Unable to save the session");
16580 char *Buffer =
new char[10000];
16585 BytesRead = FileRead(Handle, Buffer, 10000);
16586 SessionFile.write(Buffer, BytesRead);
16587 if(BytesRead < 10000)
16593 SessionFile.close();
16594 SessionFile.open(SessionFileStr.c_str(), std::ios_base::app | std::ios_base::out);
16618 if(!FileExists(TimetableFileName))
16625 ErrorFile.open(ErrorFileStr.c_str(), std::ios_base::app | std::ios_base::binary);
16627 int Handle = FileOpen(TimetableFileName, fmOpenRead);
16634 Handle = FileOpen(TimetableFileName, fmOpenRead);
16644 char *Buffer =
new char[10000];
16649 BytesRead = FileRead(Handle, Buffer, 10000);
16650 ErrorFile.write(Buffer, BytesRead);
16651 if(BytesRead < 10000)
16658 ErrorFile.open(ErrorFileStr.c_str(), std::ios_base::app | std::ios_base::out);
16686 int TempTTFileNumber = 0;
16688 while(FileExists(
CurDir +
"\\TmpTT" + AnsiString(TempTTFileNumber) +
".tmp"))
16690 TempTTFileNumber++;
16698 if(!TTBFile.fail())
16700 char *Buffer =
new char[10000];
16701 char TempChar = (char)(SessionFile.peek());
16702 if(TempChar ==
'\n')
16703 SessionFile.get(TempChar);
16704 if(!SessionFile.getline(Buffer, 10000,
'\0'))
16713 for(
int x = 0; x < 10000; x++)
16715 if(Buffer[x] !=
'\0')
16720 while(AnsiString(Buffer) !=
"***End***")
16722 TTBFile.write(Buffer, Count);
16723 TTBFile.write(&Zero, 1);
16725 if(!SessionFile.getline(Buffer, 10000,
'\0'))
16734 for(
int x = 0; x < 10000; x++)
16736 if(Buffer[x] !=
'\0')
16746 bool GiveMessagesFalse =
false;
16747 bool CheckLocationsExistInRailwayTrue =
true;
16750 std::ifstream TTBLFile(
TempTTFileName.c_str(), std::ios_base::binary);
16751 if(TTBLFile.is_open())
16753 bool SessionFileTrue =
true;
16784 for(
int x = 0; x < NumberOfTrainEntries; x++)
16792 for(
int y = 0; y < NumberOfTrains; y++)
16817 AnsiString OutString;
16824 while(OutString !=
"***End***")
16833 if(SessionFile.fail())
16838 int NumberOfTrainEntries;
16845 for(
int x = 0; x < NumberOfTrainEntries; x++)
16847 int NumberOfTrains;
16853 for(
int y = 0; y < NumberOfTrains; y++)
16882 bool EndOfFile =
false;
16884 char *TrainTimetableString =
new char[10000];
16888 TTBLFile.getline(TrainTimetableString, 10000,
'\0');
16889 if(TTBLFile.eof() && (TrainTimetableString[0] ==
'\0'))
16895 AnsiString OneLine(TrainTimetableString);
16896 bool FinalCallTrue =
true;
16898 CheckLocationsExistInRailway))
16900 TTBLFile.getline(TrainTimetableString, 10000,
'\0');
16901 if(TTBLFile.eof() && (TrainTimetableString[0] ==
'\0'))
16904 throw Exception(
"Timetable FinalCall error - no start time on own line, Count = 0");
16906 OneLine = AnsiString(TrainTimetableString);
16912 TTBLFile.getline(TrainTimetableString, 10000,
'\0');
16913 if(TTBLFile.eof() && (TrainTimetableString[0] ==
'\0'))
16919 OneLine = AnsiString(TrainTimetableString);
16924 throw Exception(
"Timetable FinalCall error in processing one timetable line, Count = " + AnsiString(Count));
16926 if(EndOfFile && (Count < 2))
16929 throw Exception(
"Timetable FinalCall error - too few or no relevant entries, Count = " + AnsiString(Count));
16934 delete TrainTimetableString;
16941 ShowMessage(
"Timetable secondary integrity check failed - unable to load");
16977 bool EndOfFile =
false;
16979 char *TrainTimetableString =
new char[10000];
16983 TTBLFile.getline(TrainTimetableString, 10000,
'\0');
16984 if(TTBLFile.eof() && (TrainTimetableString[0] ==
'\0'))
16990 AnsiString OneLine(TrainTimetableString);
16991 bool FinalCallTrue =
true;
16993 CheckLocationsExistInRailway))
16995 TTBLFile.getline(TrainTimetableString, 10000,
'\0');
16996 if(TTBLFile.eof() && (TrainTimetableString[0] ==
'\0'))
16999 throw Exception(
"Timetable FinalCall error - no start time on own line, Count = 0");
17001 OneLine = AnsiString(TrainTimetableString);
17007 TTBLFile.getline(TrainTimetableString, 10000,
'\0');
17008 if(TTBLFile.eof() && (TrainTimetableString[0] ==
'\0'))
17014 OneLine = AnsiString(TrainTimetableString);
17019 throw Exception(
"Timetable FinalCall error in processing one timetable line, Count = " + AnsiString(Count));
17021 if(EndOfFile && (Count < 2))
17024 throw Exception(
"Timetable FinalCall error - too few or no relevant entries, Count = " + AnsiString(Count));
17029 delete TrainTimetableString;
17061 std::ifstream InFile(FileName.c_str());
17063 int NumberOfActiveElements;
17064 bool GraphicsFollow =
false;
17066 if(InFile.is_open())
17213 if((TempString !=
"***BarriersDownVector***") && (TempString !=
"***Timetable***"))
17219 if(TempString ==
"***BarriersDownVector***")
17257 ShowMessage(
"Session file failed to open - reason not known, unable to load session.");
17264 InFile.open(FileName.c_str());
17265 if(InFile.is_open())
17286 bool GraphicsFollow =
false;
17407 if((TempString !=
"***BarriersDownVector***") && (TempString !=
"***Timetable***"))
17413 if(TempString ==
"***BarriersDownVector***")
17492 InFile.get(TempChar);
17493 while(!InFile.eof() && ((TempChar ==
'\n') || (TempChar ==
'\0')))
17495 InFile.get(TempChar);
17526 double PowerDouble;
17556 AnsiString TempString =
"", Line1 =
"", Line2 =
"", Line3 =
"", Line4 =
"", Line5 =
"";
17557 char *Buffer =
new char[1000];
17560 InFile.get(TempChar);
17561 InFile.getline(Buffer, 1000);
17562 TempString = AnsiString(Buffer);
17563 while(TempString !=
"***End of performance file***")
17567 InFile.getline(Buffer, 1000);
17568 TempString = AnsiString(Buffer);
17579 AnsiString TempString =
"";
17582 InFile.get(TempChar);
17583 if(TempChar !=
'\n')
17593 while(TempString !=
"***End of performance file***")
17614 AnsiString OneLine = Text.SubString(1, Text.Pos(
'\x0D'));
17615 while((OneLine.Length() > 0) && OneLine[OneLine.Length()] <
' ')
17616 OneLine.SetLength(OneLine.Length() - 1);
17617 Text = Text.SubString(Text.Pos(
'\x0D'), Text.Length());
17618 while((Text.Length() > 0) && Text[1] <
' ')
17619 Text = Text.SubString(2, (Text.Length() - 1));
17620 OutFile << OneLine.c_str() <<
'\n';
17639 InfoPanel->Caption =
"PRE-START: Select AUTOMATIC SIGNAL ROUTE start signal, or left click points to change manually";
17641 InfoPanel->Caption =
"OPERATING: Select AUTOMATIC SIGNAL ROUTE start signal, or left click points to change manually";
17651 InfoPanel->Caption =
"PRE-START: Select PREFERRED ROUTE start signal, or left click points to change manually";
17653 InfoPanel->Caption =
"OPERATING: Select PREFERRED ROUTE start signal, or left click points to change manually";
17663 InfoPanel->Caption =
"PRE-START: Select UNRESTRICTED ROUTE start location, or left click points to change manually";
17665 InfoPanel->Caption =
"OPERATING: Select UNRESTRICTED ROUTE start location, or left click points to change manually";
17676 InfoPanel->Caption =
"PRE-START: Select UNRESTRICTED ROUTE start location, or left click points to change manually";
17678 InfoPanel->Caption =
"OPERATING: Select UNRESTRICTED ROUTE start location, or left click points to change manually";
17704 InfoPanel->Caption =
"Left click screen to zoom in at that position";
17709 InfoPanel->Caption =
"PAUSED: Railway state changes disabled";
17782 Screen->Cursor = TCursor(-11);
17783 AnsiString ErrorFileStr =
CurDir +
"\\errorlog.err";
17784 std::ofstream ErrorFile(ErrorFileStr.c_str());
17786 if(!(ErrorFile.fail()))
17789 int ScreenX = Mouse->CursorPos.x -
MainScreen->ClientOrigin.x;
17790 int ScreenY = Mouse->CursorPos.y -
MainScreen->ClientOrigin.y;
17791 AnsiString MouseStr =
"Posx: " + AnsiString(ScreenX) +
"; Posy: " + AnsiString(ScreenY);
17801 ErrorFile << Item.c_str() <<
'\n';
17808 ErrorFile << Item.c_str() <<
'\n';
17917 Screen->Cursor = TCursor(-2);
17934 int TempTTFileNumber = 0;
17936 while(FileExists(
CurDir +
"\\TmpTT" + AnsiString(TempTTFileNumber) +
".tmp"))
17938 TempTTFileNumber++;
17941 int InHandle = FileOpen(InFileName, fmOpenRead);
17944 while(InHandle < 0)
17946 InHandle = FileOpen(InFileName, fmOpenRead);
17951 ShowMessage(
"Failed to open timetable file, make sure it's not open in another application");
17959 while(OutHandle < 0)
17966 ShowMessage(
"Failed to save temporary timetable file, sessions can't be saved - try again, may only be a temporary problem");
17967 FileClose(InHandle);
17972 int CountIn, CountOut;
17973 char *Buffer =
new char[10000];
17977 CountIn = FileRead(InHandle, Buffer, 10000);
17978 CountOut = FileWrite(OutHandle, Buffer, CountIn);
17979 if(CountOut != CountIn)
17981 ShowMessage(
"Error in writing to the temporary timetable file, sessions can't be saved - try again, may only be a temporary problem");
17983 FileClose(InHandle);
17984 FileClose(OutHandle);
17988 if(CountIn < 10000)
17992 FileClose(InHandle);
17993 FileClose(OutHandle);
18038 int VarElements = 0;
18039 bool NamedLocPresent =
false;
18047 throw Exception(
"Error - failed to find track element at " + AnsiString(TE.
HLoc) +
" & " + AnsiString(TE.
VLoc) +
" in SetLengths");
18054 NamedLocPresent =
true;
18060 if(SpeedLimit != -1)
18065 if(SpeedLimit != -1)
18075 if((NamedLocPresent) && (VarElements > 0) && ((Distance / VarElements) < 50))
18077 ShowMessage(
"Note: Named location elements are quite short. If they are too short the simulation might depart too far from reality.");
18080 if((NamedLocPresent) && (VarElements > 0) && ((Distance / VarElements) > 200))
18082 ShowMessage(
"Note: Named location elements are quite long. If they are too long the simulation might depart too far from reality.");
18091 if((VarElements * 20) > Distance)
18093 ShowMessage(
"Required distance is less than the minimum, will set each element to the minimum (20m)");
18094 Distance = (VarElements * 20);
18096 if(VarElements == 0)
18099 ShowMessage(
"No elements selected");
18105 int RemainingDistance = Distance, RemainingVarElements = VarElements, NextLength = RemainingDistance / VarElements;
18113 if(NextLength < 20)
18137 RemainingDistance -= NextLength;
18138 RemainingVarElements--;
18139 if(RemainingVarElements > 0)
18140 NextLength = RemainingDistance / RemainingVarElements;
18165 ShowMessage(
"Nothing to save!");
18170 SaveRailwayDialog->Filter =
"Development file (*.dev)|*.dev|Railway file (*.rly)|*.rly";
18181 Screen->Cursor = TCursor(-11);
18183 AnsiString Extension =
"";
18191 if(!(VecFile.fail()))
18219 if((LastChar ==
'y') || (LastChar ==
'Y'))
18247 ShowMessage(
"File open failed prior to save");
18251 ShowMessage(
"Can't save: extension must be either '.dev', or '.rly' with railway ready for operation");
18253 Screen->Cursor = TCursor(-2);
18351 bool TextFound =
false;
18374 AnsiString(VPos) +
"," + AnsiString((
short)UseEnteredPosition));
18375 int VPosHi, VPosLo, TextPosHi, TextPosLo;
18378 if(!UseEnteredPosition)
18385 int Depth = abs(Font->Height);
18386 TextPosHi = VPosHi + 20;
18387 TextPosLo = VPosLo - Depth - 4;
18390 if(TextPosLo >= ScreenPosLo)
18392 else if(TextPosHi < ScreenPosHi)
18395 VPos = ScreenPosLo + 288;
18441 catch(
const Exception &e)
18518 AnsiString OpTimeToActDisplay;
18519 AnsiString OpTimeToActString;
18520 AnsiString HeadCode;
18521 float OpTimeToActFloat;
18533 HeadCode = HCandTrainPosParam.first;
18534 if(OpTimeToActFloat < 0.25)
18536 OpTimeToActString =
"NOW";
18538 else if(OpTimeToActFloat < 1)
18540 OpTimeToActString =
"<1";
18544 OpTimeToActString = AnsiString(floor(OpTimeToActFloat));
18546 if(OpTimeToActFloat < 60)
18548 OpTimeToActDisplay = HeadCode + AnsiString(
'\t') + OpTimeToActString;
18549 OAListBox->Items->Add(OpTimeToActDisplay);
18573 TPicture *PicPtr =
new TPicture;
18575 UGME.second = PicPtr;
18586 catch(
const EInvalidGraphic &e)
18589 "Incorrect file format, the file can't be loaded.\nEnsure that the file you want is a valid graphic file with extension .bmp, .gif, .jpg, or .png");
18591 catch(
const Exception &e)